mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-07-06 13:55:22 +02:00
Merge tag 'v5.2.42' into v5.2/standard/base
This is the 5.2.42 stable release
This commit is contained in:
commit
e1e56c0730
|
@ -8,3 +8,4 @@ HD-Audio
|
|||
models
|
||||
controls
|
||||
dp-mst
|
||||
realtek-pc-beep
|
||||
|
|
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.
|
|
@ -4264,6 +4264,7 @@ F: crypto/
|
|||
F: drivers/crypto/
|
||||
F: include/crypto/
|
||||
F: include/linux/crypto*
|
||||
F: lib/crypto/
|
||||
|
||||
CRYPTOGRAPHIC RANDOM NUMBER GENERATOR
|
||||
M: Neil Horman <nhorman@tuxdriver.com>
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 5
|
||||
PATCHLEVEL = 2
|
||||
SUBLEVEL = 41
|
||||
SUBLEVEL = 42
|
||||
EXTRAVERSION =
|
||||
NAME = Bobtail Squid
|
||||
|
||||
|
|
|
@ -105,6 +105,7 @@
|
|||
&sdhci {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&emmc_gpio34 &gpclk2_gpio43>;
|
||||
mmc-pwrseq = <&wifi_pwrseq>;
|
||||
non-removable;
|
||||
|
|
|
@ -24,12 +24,12 @@
|
|||
|
||||
&cpsw_emac0 {
|
||||
phy-handle = <ðphy0>;
|
||||
phy-mode = "rgmii";
|
||||
phy-mode = "rgmii-id";
|
||||
};
|
||||
|
||||
&cpsw_emac1 {
|
||||
phy-handle = <ðphy1>;
|
||||
phy-mode = "rgmii";
|
||||
phy-mode = "rgmii-id";
|
||||
};
|
||||
|
||||
&davinci_mdio {
|
||||
|
|
|
@ -33,12 +33,12 @@
|
|||
|
||||
&cpsw_emac0 {
|
||||
phy-handle = <ðphy0>;
|
||||
phy-mode = "rgmii";
|
||||
phy-mode = "rgmii-id";
|
||||
};
|
||||
|
||||
&cpsw_emac1 {
|
||||
phy-handle = <ðphy1>;
|
||||
phy-mode = "rgmii";
|
||||
phy-mode = "rgmii-id";
|
||||
};
|
||||
|
||||
&davinci_mdio {
|
||||
|
|
|
@ -24,12 +24,12 @@
|
|||
|
||||
&cpsw_emac0 {
|
||||
phy-handle = <ðphy0>;
|
||||
phy-mode = "rgmii";
|
||||
phy-mode = "rgmii-id";
|
||||
};
|
||||
|
||||
&cpsw_emac1 {
|
||||
phy-handle = <ðphy1>;
|
||||
phy-mode = "rgmii";
|
||||
phy-mode = "rgmii-id";
|
||||
};
|
||||
|
||||
&davinci_mdio {
|
||||
|
|
|
@ -115,7 +115,7 @@
|
|||
gpio-sck = <&gpy3 1 GPIO_ACTIVE_HIGH>;
|
||||
gpio-mosi = <&gpy3 3 GPIO_ACTIVE_HIGH>;
|
||||
num-chipselects = <1>;
|
||||
cs-gpios = <&gpy4 3 GPIO_ACTIVE_HIGH>;
|
||||
cs-gpios = <&gpy4 3 GPIO_ACTIVE_LOW>;
|
||||
|
||||
lcd@0 {
|
||||
compatible = "samsung,ld9040";
|
||||
|
@ -124,8 +124,6 @@
|
|||
vci-supply = <&ldo17_reg>;
|
||||
reset-gpios = <&gpy4 5 GPIO_ACTIVE_HIGH>;
|
||||
spi-max-frequency = <1200000>;
|
||||
spi-cpol;
|
||||
spi-cpha;
|
||||
power-on-delay = <10>;
|
||||
reset-delay = <10>;
|
||||
panel-width-mm = <90>;
|
||||
|
|
|
@ -107,14 +107,14 @@
|
|||
regulators {
|
||||
vdd_arm: buck1 {
|
||||
regulator-name = "vdd_arm";
|
||||
regulator-min-microvolt = <730000>;
|
||||
regulator-min-microvolt = <925000>;
|
||||
regulator-max-microvolt = <1380000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
vdd_soc: buck2 {
|
||||
regulator-name = "vdd_soc";
|
||||
regulator-min-microvolt = <730000>;
|
||||
regulator-min-microvolt = <1150000>;
|
||||
regulator-max-microvolt = <1380000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
|
|
@ -1040,9 +1040,8 @@
|
|||
compatible = "fsl,imx6q-fec";
|
||||
reg = <0x02188000 0x4000>;
|
||||
interrupt-names = "int0", "pps";
|
||||
interrupts-extended =
|
||||
<&intc 0 118 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts = <0 118 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<0 119 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&clks IMX6QDL_CLK_ENET>,
|
||||
<&clks IMX6QDL_CLK_ENET>,
|
||||
<&clks IMX6QDL_CLK_ENET_REF>;
|
||||
|
|
|
@ -77,7 +77,6 @@
|
|||
};
|
||||
|
||||
&fec {
|
||||
/delete-property/interrupts-extended;
|
||||
interrupts = <0 118 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<0 119 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
|
|
|
@ -115,6 +115,18 @@
|
|||
fsl,magic-packet;
|
||||
};
|
||||
|
||||
&flexcan1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_flexcan1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&flexcan2 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_flexcan2>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&gpmi {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_gpmi_nand>;
|
||||
|
@ -327,12 +339,11 @@
|
|||
|
||||
&iomuxc {
|
||||
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_usbc_det>;
|
||||
|
||||
pinctrl_gpio1: gpio1-grp {
|
||||
fsl,pins = <
|
||||
MX7D_PAD_ENET1_RGMII_RD3__GPIO7_IO3 0x74 /* SODIMM 55 */
|
||||
MX7D_PAD_ENET1_RGMII_RD2__GPIO7_IO2 0x74 /* SODIMM 63 */
|
||||
MX7D_PAD_SAI1_RX_SYNC__GPIO6_IO16 0x14 /* SODIMM 77 */
|
||||
MX7D_PAD_EPDC_DATA09__GPIO2_IO9 0x14 /* SODIMM 89 */
|
||||
MX7D_PAD_EPDC_DATA08__GPIO2_IO8 0x74 /* SODIMM 91 */
|
||||
|
@ -413,6 +424,13 @@
|
|||
>;
|
||||
};
|
||||
|
||||
pinctrl_gpio7: gpio7-grp { /* Alternatively CAN1 */
|
||||
fsl,pins = <
|
||||
MX7D_PAD_ENET1_RGMII_RD3__GPIO7_IO3 0x14 /* SODIMM 55 */
|
||||
MX7D_PAD_ENET1_RGMII_RD2__GPIO7_IO2 0x14 /* SODIMM 63 */
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_i2c1_int: i2c1-int-grp { /* PMIC / TOUCH */
|
||||
fsl,pins = <
|
||||
MX7D_PAD_GPIO1_IO13__GPIO1_IO13 0x79
|
||||
|
@ -427,7 +445,6 @@
|
|||
|
||||
pinctrl_enet1: enet1grp {
|
||||
fsl,pins = <
|
||||
MX7D_PAD_ENET1_CRS__GPIO7_IO14 0x14
|
||||
MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL 0x73
|
||||
MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0 0x73
|
||||
MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1 0x73
|
||||
|
@ -456,10 +473,17 @@
|
|||
>;
|
||||
};
|
||||
|
||||
pinctrl_flexcan1: flexcan1-grp {
|
||||
fsl,pins = <
|
||||
MX7D_PAD_ENET1_RGMII_RD3__FLEXCAN1_TX 0x79 /* SODIMM 55 */
|
||||
MX7D_PAD_ENET1_RGMII_RD2__FLEXCAN1_RX 0x79 /* SODIMM 63 */
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_flexcan2: flexcan2-grp {
|
||||
fsl,pins = <
|
||||
MX7D_PAD_GPIO1_IO14__FLEXCAN2_RX 0x59
|
||||
MX7D_PAD_GPIO1_IO15__FLEXCAN2_TX 0x59
|
||||
MX7D_PAD_GPIO1_IO14__FLEXCAN2_RX 0x79 /* SODIMM 188 */
|
||||
MX7D_PAD_GPIO1_IO15__FLEXCAN2_TX 0x79 /* SODIMM 178 */
|
||||
>;
|
||||
};
|
||||
|
||||
|
@ -595,6 +619,12 @@
|
|||
>;
|
||||
};
|
||||
|
||||
pinctrl_usbc_det: gpio-usbc-det {
|
||||
fsl,pins = <
|
||||
MX7D_PAD_ENET1_CRS__GPIO7_IO14 0x14
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_usbh_reg: gpio-usbh-vbus {
|
||||
fsl,pins = <
|
||||
MX7D_PAD_UART3_CTS_B__GPIO4_IO7 0x14 /* SODIMM 129 USBH PEN */
|
||||
|
|
|
@ -849,34 +849,46 @@
|
|||
compatible = "ti,omap2-onenand";
|
||||
reg = <0 0 0x20000>; /* CS0, offset 0, IO size 128K */
|
||||
|
||||
/*
|
||||
* These timings are based on CONFIG_OMAP_GPMC_DEBUG=y reported
|
||||
* bootloader set values when booted with v5.1
|
||||
* (OneNAND Manufacturer: Samsung):
|
||||
*
|
||||
* cs0 GPMC_CS_CONFIG1: 0xfb001202
|
||||
* cs0 GPMC_CS_CONFIG2: 0x00111100
|
||||
* cs0 GPMC_CS_CONFIG3: 0x00020200
|
||||
* cs0 GPMC_CS_CONFIG4: 0x11001102
|
||||
* cs0 GPMC_CS_CONFIG5: 0x03101616
|
||||
* cs0 GPMC_CS_CONFIG6: 0x90060000
|
||||
*/
|
||||
gpmc,sync-read;
|
||||
gpmc,sync-write;
|
||||
gpmc,burst-length = <16>;
|
||||
gpmc,burst-read;
|
||||
gpmc,burst-wrap;
|
||||
gpmc,burst-write;
|
||||
gpmc,device-width = <2>; /* GPMC_DEVWIDTH_16BIT */
|
||||
gpmc,mux-add-data = <2>; /* GPMC_MUX_AD */
|
||||
gpmc,device-width = <2>;
|
||||
gpmc,mux-add-data = <2>;
|
||||
gpmc,cs-on-ns = <0>;
|
||||
gpmc,cs-rd-off-ns = <87>;
|
||||
gpmc,cs-wr-off-ns = <87>;
|
||||
gpmc,cs-rd-off-ns = <102>;
|
||||
gpmc,cs-wr-off-ns = <102>;
|
||||
gpmc,adv-on-ns = <0>;
|
||||
gpmc,adv-rd-off-ns = <10>;
|
||||
gpmc,adv-wr-off-ns = <10>;
|
||||
gpmc,oe-on-ns = <15>;
|
||||
gpmc,oe-off-ns = <87>;
|
||||
gpmc,adv-rd-off-ns = <12>;
|
||||
gpmc,adv-wr-off-ns = <12>;
|
||||
gpmc,oe-on-ns = <12>;
|
||||
gpmc,oe-off-ns = <102>;
|
||||
gpmc,we-on-ns = <0>;
|
||||
gpmc,we-off-ns = <87>;
|
||||
gpmc,rd-cycle-ns = <112>;
|
||||
gpmc,wr-cycle-ns = <112>;
|
||||
gpmc,access-ns = <81>;
|
||||
gpmc,page-burst-access-ns = <15>;
|
||||
gpmc,we-off-ns = <102>;
|
||||
gpmc,rd-cycle-ns = <132>;
|
||||
gpmc,wr-cycle-ns = <132>;
|
||||
gpmc,access-ns = <96>;
|
||||
gpmc,page-burst-access-ns = <18>;
|
||||
gpmc,bus-turnaround-ns = <0>;
|
||||
gpmc,cycle2cycle-delay-ns = <0>;
|
||||
gpmc,wait-monitoring-ns = <0>;
|
||||
gpmc,clk-activation-ns = <5>;
|
||||
gpmc,wr-data-mux-bus-ns = <30>;
|
||||
gpmc,wr-access-ns = <81>;
|
||||
gpmc,clk-activation-ns = <6>;
|
||||
gpmc,wr-data-mux-bus-ns = <36>;
|
||||
gpmc,wr-access-ns = <96>;
|
||||
gpmc,sync-clk-ps = <15000>;
|
||||
|
||||
/*
|
||||
|
|
|
@ -323,8 +323,8 @@
|
|||
interrupt-controller;
|
||||
reg = <0 0x200>;
|
||||
#interrupt-cells = <1>;
|
||||
valid-mask = <0xFFFFFFFF>;
|
||||
clear-mask = <0>;
|
||||
valid-mask = <0xffffffff>;
|
||||
clear-mask = <0xffffffff>;
|
||||
};
|
||||
|
||||
timer0: timer@200 {
|
||||
|
|
|
@ -240,8 +240,8 @@
|
|||
reg = <0 0x200>;
|
||||
interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
|
||||
#interrupt-cells = <1>;
|
||||
valid-mask = <0xFFFFFFFF>;
|
||||
clear-mask = <0>;
|
||||
valid-mask = <0xffffffff>;
|
||||
clear-mask = <0xffffffff>;
|
||||
};
|
||||
|
||||
timer0: timer@200 {
|
||||
|
|
|
@ -58,11 +58,14 @@
|
|||
|
||||
lvds-encoder {
|
||||
compatible = "ti,sn75lvds83", "lvds-encoder";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
lvds_in_vop0: endpoint {
|
||||
remote-endpoint = <&vop0_out_lvds>;
|
||||
};
|
||||
|
@ -70,11 +73,13 @@
|
|||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
lvds_out_panel: endpoint {
|
||||
remote-endpoint = <&panel_in_lvds>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
panel {
|
||||
compatible = "innolux,ee101ia-01d", "panel-lvds";
|
||||
|
@ -465,7 +470,7 @@
|
|||
non-removable;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&sd1_clk>, <&sd1_cmd>, <&sd1_bus4>;
|
||||
vmmcq-supply = <&vccio_wl>;
|
||||
vqmmc-supply = <&vccio_wl>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "okay";
|
||||
|
|
|
@ -358,8 +358,8 @@
|
|||
};
|
||||
|
||||
®_dldo3 {
|
||||
regulator-min-microvolt = <2800000>;
|
||||
regulator-max-microvolt = <2800000>;
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-name = "vdd-csi";
|
||||
};
|
||||
|
||||
|
|
|
@ -313,11 +313,11 @@
|
|||
|
||||
display_clocks: clock@1000000 {
|
||||
compatible = "allwinner,sun8i-a83t-de2-clk";
|
||||
reg = <0x01000000 0x100000>;
|
||||
clocks = <&ccu CLK_PLL_DE>,
|
||||
<&ccu CLK_BUS_DE>;
|
||||
clock-names = "mod",
|
||||
"bus";
|
||||
reg = <0x01000000 0x10000>;
|
||||
clocks = <&ccu CLK_BUS_DE>,
|
||||
<&ccu CLK_PLL_DE>;
|
||||
clock-names = "bus",
|
||||
"mod";
|
||||
resets = <&ccu RST_BUS_DE>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
|
|
|
@ -118,11 +118,11 @@
|
|||
display_clocks: clock@1000000 {
|
||||
compatible = "allwinner,sun8i-r40-de2-clk",
|
||||
"allwinner,sun8i-h3-de2-clk";
|
||||
reg = <0x01000000 0x100000>;
|
||||
clocks = <&ccu CLK_DE>,
|
||||
<&ccu CLK_BUS_DE>;
|
||||
clock-names = "mod",
|
||||
"bus";
|
||||
reg = <0x01000000 0x10000>;
|
||||
clocks = <&ccu CLK_BUS_DE>,
|
||||
<&ccu CLK_DE>;
|
||||
clock-names = "bus",
|
||||
"mod";
|
||||
resets = <&ccu RST_BUS_DE>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
|
@ -266,6 +266,16 @@
|
|||
#phy-cells = <1>;
|
||||
};
|
||||
|
||||
ahci: sata@1c18000 {
|
||||
compatible = "allwinner,sun8i-r40-ahci";
|
||||
reg = <0x01c18000 0x1000>;
|
||||
interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&ccu CLK_BUS_SATA>, <&ccu CLK_SATA>;
|
||||
resets = <&ccu RST_BUS_SATA>;
|
||||
reset-names = "ahci";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
ehci1: usb@1c19000 {
|
||||
compatible = "allwinner,sun8i-r40-ehci", "generic-ehci";
|
||||
reg = <0x01c19000 0x100>;
|
||||
|
@ -552,17 +562,6 @@
|
|||
#size-cells = <0>;
|
||||
};
|
||||
|
||||
ahci: sata@1c18000 {
|
||||
compatible = "allwinner,sun8i-r40-ahci";
|
||||
reg = <0x01c18000 0x1000>;
|
||||
interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&ccu CLK_BUS_SATA>, <&ccu CLK_SATA>;
|
||||
resets = <&ccu RST_BUS_SATA>;
|
||||
reset-names = "ahci";
|
||||
status = "disabled";
|
||||
|
||||
};
|
||||
|
||||
gmac: ethernet@1c50000 {
|
||||
compatible = "allwinner,sun8i-r40-gmac";
|
||||
syscon = <&ccu>;
|
||||
|
|
|
@ -103,11 +103,11 @@
|
|||
|
||||
display_clocks: clock@1000000 {
|
||||
compatible = "allwinner,sun8i-v3s-de2-clk";
|
||||
reg = <0x01000000 0x100000>;
|
||||
clocks = <&ccu CLK_DE>,
|
||||
<&ccu CLK_BUS_DE>;
|
||||
clock-names = "mod",
|
||||
"bus";
|
||||
reg = <0x01000000 0x10000>;
|
||||
clocks = <&ccu CLK_BUS_DE>,
|
||||
<&ccu CLK_DE>;
|
||||
clock-names = "bus",
|
||||
"mod";
|
||||
resets = <&ccu RST_BUS_DE>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
|
|
|
@ -113,11 +113,11 @@
|
|||
|
||||
display_clocks: clock@1000000 {
|
||||
/* compatible is in per SoC .dtsi file */
|
||||
reg = <0x01000000 0x100000>;
|
||||
clocks = <&ccu CLK_DE>,
|
||||
<&ccu CLK_BUS_DE>;
|
||||
clock-names = "mod",
|
||||
"bus";
|
||||
reg = <0x01000000 0x10000>;
|
||||
clocks = <&ccu CLK_BUS_DE>,
|
||||
<&ccu CLK_DE>;
|
||||
clock-names = "bus",
|
||||
"mod";
|
||||
resets = <&ccu RST_BUS_DE>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
|
|
|
@ -520,6 +520,7 @@ config SOC_IMX6UL
|
|||
bool "i.MX6 UltraLite support"
|
||||
select PINCTRL_IMX6UL
|
||||
select SOC_IMX6
|
||||
select ARM_ERRATA_814220
|
||||
|
||||
help
|
||||
This enables support for Freescale i.MX6 UltraLite processor.
|
||||
|
@ -556,6 +557,7 @@ config SOC_IMX7D
|
|||
select PINCTRL_IMX7D
|
||||
select SOC_IMX7D_CA7 if ARCH_MULTI_V7
|
||||
select SOC_IMX7D_CM4 if ARM_SINGLE_ARMV7M
|
||||
select ARM_ERRATA_814220 if ARCH_MULTI_V7
|
||||
help
|
||||
This enables support for Freescale i.MX7 Dual processor.
|
||||
|
||||
|
|
|
@ -927,7 +927,11 @@ static inline void emit_a32_rsh_i64(const s8 dst[],
|
|||
rd = arm_bpf_get_reg64(dst, tmp, ctx);
|
||||
|
||||
/* 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_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);
|
||||
|
@ -953,7 +957,11 @@ static inline void emit_a32_arsh_i64(const s8 dst[],
|
|||
rd = arm_bpf_get_reg64(dst, tmp, ctx);
|
||||
|
||||
/* 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_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);
|
||||
|
@ -990,21 +998,35 @@ static inline void emit_a32_mul_r64(const s8 dst[], const s8 src[],
|
|||
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 */
|
||||
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];
|
||||
s32 off_max;
|
||||
s8 rd;
|
||||
|
||||
rd = arm_bpf_get_reg32(dst, tmp[1], ctx);
|
||||
|
||||
if (sz == BPF_H)
|
||||
off_max = 0xff;
|
||||
else
|
||||
off_max = 0xfff;
|
||||
|
||||
if (off < 0 || off > off_max) {
|
||||
if (!is_ldst_imm(off, sz)) {
|
||||
emit_a32_mov_i(tmp[0], off, ctx);
|
||||
emit(ARM_ADD_R(tmp[0], tmp[0], rd), ctx);
|
||||
rd = tmp[0];
|
||||
|
@ -1033,18 +1055,12 @@ static inline void emit_str_r(const s8 dst, const s8 src[],
|
|||
|
||||
/* dst = *(size*)(src + off) */
|
||||
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 *rd = is_stacked(dst_lo) ? tmp : dst;
|
||||
s8 rm = src;
|
||||
s32 off_max;
|
||||
|
||||
if (sz == BPF_H)
|
||||
off_max = 0xff;
|
||||
else
|
||||
off_max = 0xfff;
|
||||
|
||||
if (off < 0 || off > off_max) {
|
||||
if (!is_ldst_imm(off, sz)) {
|
||||
emit_a32_mov_i(tmp[0], off, ctx);
|
||||
emit(ARM_ADD_R(tmp[0], tmp[0], src), ctx);
|
||||
rm = tmp[0];
|
||||
|
|
|
@ -67,6 +67,10 @@ stack_protector_prepare: prepare0
|
|||
include/generated/asm-offsets.h))
|
||||
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)
|
||||
KBUILD_CPPFLAGS += -mbig-endian
|
||||
CHECKFLAGS += -D__AARCH64EB__
|
||||
|
|
|
@ -227,11 +227,11 @@
|
|||
|
||||
display_clocks: clock@0 {
|
||||
compatible = "allwinner,sun50i-a64-de2-clk";
|
||||
reg = <0x0 0x100000>;
|
||||
clocks = <&ccu CLK_DE>,
|
||||
<&ccu CLK_BUS_DE>;
|
||||
clock-names = "mod",
|
||||
"bus";
|
||||
reg = <0x0 0x10000>;
|
||||
clocks = <&ccu CLK_BUS_DE>,
|
||||
<&ccu CLK_DE>;
|
||||
clock-names = "bus",
|
||||
"mod";
|
||||
resets = <&ccu RST_BUS_DE>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
|
|
|
@ -119,12 +119,12 @@
|
|||
|
||||
ethernet@e4000 {
|
||||
phy-handle = <&rgmii_phy1>;
|
||||
phy-connection-type = "rgmii-txid";
|
||||
phy-connection-type = "rgmii-id";
|
||||
};
|
||||
|
||||
ethernet@e6000 {
|
||||
phy-handle = <&rgmii_phy2>;
|
||||
phy-connection-type = "rgmii-txid";
|
||||
phy-connection-type = "rgmii-id";
|
||||
};
|
||||
|
||||
ethernet@e8000 {
|
||||
|
|
|
@ -127,12 +127,12 @@
|
|||
&fman0 {
|
||||
ethernet@e4000 {
|
||||
phy-handle = <&rgmii_phy1>;
|
||||
phy-connection-type = "rgmii";
|
||||
phy-connection-type = "rgmii-id";
|
||||
};
|
||||
|
||||
ethernet@e6000 {
|
||||
phy-handle = <&rgmii_phy2>;
|
||||
phy-connection-type = "rgmii";
|
||||
phy-connection-type = "rgmii-id";
|
||||
};
|
||||
|
||||
ethernet@e8000 {
|
||||
|
|
|
@ -364,6 +364,7 @@
|
|||
pinctrl-0 = <&cp0_copper_eth_phy_reset>;
|
||||
reset-gpios = <&cp0_gpio2 11 GPIO_ACTIVE_LOW>;
|
||||
reset-assert-us = <10000>;
|
||||
reset-deassert-us = <10000>;
|
||||
};
|
||||
|
||||
switch0: switch0@4 {
|
||||
|
|
|
@ -256,6 +256,7 @@
|
|||
interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
|
||||
dma-coherent;
|
||||
power-domains = <&k3_pds 151>;
|
||||
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 */
|
||||
<&k3_clks 151 9>; /* set PIPE3_TXB_CLK to CLK_12M_RC/256 (for HS only) */
|
||||
|
@ -295,6 +296,7 @@
|
|||
interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
|
||||
dma-coherent;
|
||||
power-domains = <&k3_pds 152>;
|
||||
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 */
|
||||
|
||||
|
|
|
@ -211,7 +211,7 @@ alternative_endif
|
|||
|
||||
.macro user_alt, label, oldinstr, newinstr, cond
|
||||
9999: alternative_insn "\oldinstr", "\newinstr", \cond
|
||||
_ASM_EXTABLE 9999b, \label
|
||||
_asm_extable 9999b, \label
|
||||
.endm
|
||||
|
||||
/*
|
||||
|
|
|
@ -601,7 +601,7 @@ static struct undef_hook setend_hooks[] = {
|
|||
},
|
||||
{
|
||||
/* Thumb mode */
|
||||
.instr_mask = 0x0000fff7,
|
||||
.instr_mask = 0xfffffff7,
|
||||
.instr_val = 0x0000b650,
|
||||
.pstate_mask = (PSR_AA32_T_BIT | PSR_AA32_MODE_MASK),
|
||||
.pstate_val = (PSR_AA32_T_BIT | PSR_AA32_MODE_USR),
|
||||
|
|
|
@ -172,10 +172,7 @@
|
|||
addi r6, 0xe
|
||||
cpwcr r6, cpcr30
|
||||
|
||||
lsri r6, 28
|
||||
addi r6, 2
|
||||
lsli r6, 28
|
||||
addi r6, 0xe
|
||||
movi r6, 0
|
||||
cpwcr r6, cpcr31
|
||||
.endm
|
||||
|
||||
|
|
|
@ -10,11 +10,6 @@
|
|||
#define MTCR_DIST 0xC0006420
|
||||
#define MFCR_DIST 0xC0006020
|
||||
|
||||
void __init init_fpu(void)
|
||||
{
|
||||
mtcr("cr<1, 2>", 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* fpu_libc_helper() is to help libc to excute:
|
||||
* - mfcr %a, cr<1, 2>
|
||||
|
|
|
@ -230,11 +230,8 @@
|
|||
addi r6, 0x1ce
|
||||
mtcr r6, cr<30, 15> /* Set MSA0 */
|
||||
|
||||
lsri r6, 28
|
||||
addi r6, 2
|
||||
lsli r6, 28
|
||||
addi r6, 0x1ce
|
||||
mtcr r6, cr<31, 15> /* Set MSA1 */
|
||||
movi r6, 0
|
||||
mtcr r6, cr<31, 15> /* Clr MSA1 */
|
||||
|
||||
/* enable MMU */
|
||||
mfcr r6, cr18
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
|
||||
int fpu_libc_helper(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 restore_from_user_fp(struct user_fp *user_fp);
|
||||
|
|
|
@ -43,6 +43,7 @@ extern struct cpuinfo_csky cpu_data[];
|
|||
struct thread_struct {
|
||||
unsigned long ksp; /* kernel stack pointer */
|
||||
unsigned long sr; /* saved status register */
|
||||
unsigned long trap_no; /* saved status register */
|
||||
|
||||
/* FPU regs */
|
||||
struct user_fp __aligned(16) user_fp;
|
||||
|
|
|
@ -21,6 +21,11 @@ END(_start)
|
|||
ENTRY(_start_smp_secondary)
|
||||
SETUP_MMU
|
||||
|
||||
/* copy msa1 from CPU0 */
|
||||
lrw r6, secondary_msa1
|
||||
ld.w r6, (r6, 0)
|
||||
mtcr r6, cr<31, 15>
|
||||
|
||||
/* set stack point */
|
||||
lrw r6, secondary_stack
|
||||
ld.w r6, (r6, 0)
|
||||
|
|
|
@ -24,26 +24,9 @@ struct screen_info screen_info = {
|
|||
};
|
||||
#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)
|
||||
{
|
||||
unsigned long zone_size[MAX_NR_ZONES];
|
||||
unsigned long zhole_size[MAX_NR_ZONES];
|
||||
signed long size;
|
||||
|
||||
memblock_reserve(__pa(_stext), _end - _stext);
|
||||
|
@ -57,54 +40,36 @@ static void __init csky_memblock_init(void)
|
|||
memblock_dump_all();
|
||||
|
||||
memset(zone_size, 0, sizeof(zone_size));
|
||||
memset(zhole_size, 0, sizeof(zhole_size));
|
||||
|
||||
min_low_pfn = PFN_UP(memblock_start_of_DRAM());
|
||||
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;
|
||||
max_low_pfn = max_pfn = PFN_DOWN(memblock_end_of_DRAM());
|
||||
|
||||
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] =
|
||||
PFN_DOWN(memblock_start_of_REG1()) - min_low_pfn;
|
||||
zhole_size[ZONE_NORMAL] =
|
||||
PFN_DOWN(memblock_start_of_REG1()) - max_low_pfn;
|
||||
PFN_DOWN(SSEG_SIZE - PHYS_OFFSET_OFFSET);
|
||||
max_low_pfn = min_low_pfn + zone_size[ZONE_NORMAL];
|
||||
} else {
|
||||
if (size <= PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET))
|
||||
zone_size[ZONE_NORMAL] = max_pfn - min_low_pfn;
|
||||
else {
|
||||
zone_size[ZONE_NORMAL] =
|
||||
PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET);
|
||||
max_low_pfn = min_low_pfn + zone_size[ZONE_NORMAL];
|
||||
}
|
||||
write_mmu_msa1(read_mmu_msa0() + SSEG_SIZE);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
size = 0;
|
||||
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;
|
||||
zone_size[ZONE_HIGHMEM] = max_pfn - max_low_pfn;
|
||||
|
||||
highstart_pfn = max_low_pfn;
|
||||
highend_pfn = max_pfn;
|
||||
#endif
|
||||
memblock_set_current_limit(PFN_PHYS(max_low_pfn));
|
||||
|
||||
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)
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
#include <asm/sections.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#ifdef CONFIG_CPU_HAS_FPU
|
||||
#include <abi/fpu.h>
|
||||
#endif
|
||||
|
||||
struct ipi_data_struct {
|
||||
unsigned long bits ____cacheline_aligned;
|
||||
|
@ -156,6 +159,8 @@ volatile unsigned int secondary_hint;
|
|||
volatile unsigned int secondary_ccr;
|
||||
volatile unsigned int secondary_stack;
|
||||
|
||||
unsigned long secondary_msa1;
|
||||
|
||||
int __cpu_up(unsigned int cpu, struct task_struct *tidle)
|
||||
{
|
||||
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;
|
||||
secondary_hint = mfcr("cr31");
|
||||
secondary_ccr = mfcr("cr18");
|
||||
secondary_msa1 = read_mmu_msa1();
|
||||
|
||||
/*
|
||||
* 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;
|
||||
unsigned long vector;
|
||||
siginfo_t info;
|
||||
struct task_struct *tsk = current;
|
||||
|
||||
vector = (mfcr("psr") >> 16) & 0xff;
|
||||
vector = (regs->sr >> 16) & 0xff;
|
||||
|
||||
switch (vector) {
|
||||
case VEC_ZERODIV:
|
||||
|
@ -128,6 +129,7 @@ asmlinkage void trap_c(struct pt_regs *regs)
|
|||
sig = SIGTRAP;
|
||||
break;
|
||||
case VEC_ILLEGAL:
|
||||
tsk->thread.trap_no = vector;
|
||||
#ifndef CONFIG_CPU_NO_USER_BKPT
|
||||
if (*(uint16_t *)instruction_pointer(regs) != USR_BKPT)
|
||||
#endif
|
||||
|
@ -143,15 +145,19 @@ asmlinkage void trap_c(struct pt_regs *regs)
|
|||
sig = SIGTRAP;
|
||||
break;
|
||||
case VEC_ACCESS:
|
||||
tsk->thread.trap_no = vector;
|
||||
return buserr(regs);
|
||||
#ifdef CONFIG_CPU_NEED_SOFTALIGN
|
||||
case VEC_ALIGN:
|
||||
tsk->thread.trap_no = vector;
|
||||
return csky_alignment(regs);
|
||||
#endif
|
||||
#ifdef CONFIG_CPU_HAS_FPU
|
||||
case VEC_FPE:
|
||||
tsk->thread.trap_no = vector;
|
||||
return fpu_fpe(regs);
|
||||
case VEC_PRIV:
|
||||
tsk->thread.trap_no = vector;
|
||||
if (fpu_libc_helper(regs))
|
||||
return;
|
||||
#endif
|
||||
|
@ -159,5 +165,8 @@ asmlinkage void trap_c(struct pt_regs *regs)
|
|||
sig = SIGSEGV;
|
||||
break;
|
||||
}
|
||||
|
||||
tsk->thread.trap_no = vector;
|
||||
|
||||
send_sig(sig, current, 0);
|
||||
}
|
||||
|
|
|
@ -179,11 +179,14 @@ bad_area:
|
|||
bad_area_nosemaphore:
|
||||
/* User mode accesses just cause a SIGSEGV */
|
||||
if (user_mode(regs)) {
|
||||
tsk->thread.trap_no = (regs->sr >> 16) & 0xff;
|
||||
force_sig_fault(SIGSEGV, si_code, (void __user *)address, current);
|
||||
return;
|
||||
}
|
||||
|
||||
no_context:
|
||||
tsk->thread.trap_no = (regs->sr >> 16) & 0xff;
|
||||
|
||||
/* Are we prepared to handle this kernel fault? */
|
||||
if (fixup_exception(regs))
|
||||
return;
|
||||
|
@ -198,6 +201,8 @@ no_context:
|
|||
die_if_kernel("Oops", regs, write);
|
||||
|
||||
out_of_memory:
|
||||
tsk->thread.trap_no = (regs->sr >> 16) & 0xff;
|
||||
|
||||
/*
|
||||
* 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).
|
||||
|
@ -206,6 +211,8 @@ out_of_memory:
|
|||
return;
|
||||
|
||||
do_sigbus:
|
||||
tsk->thread.trap_no = (regs->sr >> 16) & 0xff;
|
||||
|
||||
up_read(&mm->mmap_sem);
|
||||
|
||||
/* Kernel mode? Handle exceptions or die */
|
||||
|
|
|
@ -2199,6 +2199,9 @@ static int octeon_irq_cib_map(struct irq_domain *d,
|
|||
}
|
||||
|
||||
cd = kzalloc(sizeof(*cd), GFP_KERNEL);
|
||||
if (!cd)
|
||||
return -ENOMEM;
|
||||
|
||||
cd->host_data = host_data;
|
||||
cd->bit = hw;
|
||||
|
||||
|
|
|
@ -1483,6 +1483,7 @@ static void build_r4000_tlb_refill_handler(void)
|
|||
|
||||
static void setup_pw(void)
|
||||
{
|
||||
unsigned int pwctl;
|
||||
unsigned long pgd_i, pgd_w;
|
||||
#ifndef __PAGETABLE_PMD_FOLDED
|
||||
unsigned long pmd_i, pmd_w;
|
||||
|
@ -1509,6 +1510,7 @@ static void setup_pw(void)
|
|||
|
||||
pte_i = ilog2(_PAGE_GLOBAL);
|
||||
pte_w = 0;
|
||||
pwctl = 1 << 30; /* Set PWDirExt */
|
||||
|
||||
#ifndef __PAGETABLE_PMD_FOLDED
|
||||
write_c0_pwfield(pgd_i << 24 | pmd_i << 12 | pt_i << 6 | pte_i);
|
||||
|
@ -1519,8 +1521,9 @@ static void setup_pw(void)
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
|
||||
write_c0_pwctl(1 << 6 | psn);
|
||||
pwctl |= (1 << 6 | psn);
|
||||
#endif
|
||||
write_c0_pwctl(pwctl);
|
||||
write_c0_kpgd((long)swapper_pg_dir);
|
||||
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);
|
||||
#endif
|
||||
|
||||
static inline pmd_t hash__pmd_mkdevmap(pmd_t pmd)
|
||||
{
|
||||
BUG();
|
||||
return pmd;
|
||||
}
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#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)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
|
@ -272,6 +272,12 @@ extern pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm,
|
|||
unsigned long addr, pmd_t *pmdp);
|
||||
extern int hash__has_transparent_hugepage(void);
|
||||
#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 /* _ASM_POWERPC_BOOK3S_64_HASH_64K_H */
|
||||
|
|
|
@ -1295,7 +1295,9 @@ extern void serialize_against_pte_lookup(struct mm_struct *mm);
|
|||
|
||||
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)
|
||||
|
|
|
@ -257,6 +257,11 @@ extern pmd_t radix__pmdp_huge_get_and_clear(struct mm_struct *mm,
|
|||
extern int radix__has_transparent_hugepage(void);
|
||||
#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,
|
||||
unsigned long page_size,
|
||||
unsigned long phys);
|
||||
|
|
|
@ -27,12 +27,12 @@ struct drmem_lmb_info {
|
|||
extern struct drmem_lmb_info *drmem_info;
|
||||
|
||||
#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) \
|
||||
for_each_drmem_lmb_in_range((lmb), \
|
||||
&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
|
||||
|
|
|
@ -139,7 +139,6 @@ static void __init cpufeatures_setup_cpu(void)
|
|||
/* Initialize the base environment -- clear FSCR/HFSCR. */
|
||||
hv_mode = !!(mfmsr() & MSR_HV);
|
||||
if (hv_mode) {
|
||||
/* CPU_FTR_HVMODE is used early in PACA setup */
|
||||
cur_cpu_spec->cpu_features |= CPU_FTR_HVMODE;
|
||||
mtspr(SPRN_HFSCR, 0);
|
||||
}
|
||||
|
|
|
@ -264,6 +264,9 @@ int kprobe_handler(struct pt_regs *regs)
|
|||
if (user_mode(regs))
|
||||
return 0;
|
||||
|
||||
if (!(regs->msr & MSR_IR) || !(regs->msr & MSR_DR))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* We don't want to be preempted for the entire
|
||||
* duration of kprobe processing
|
||||
|
|
|
@ -134,7 +134,7 @@ static struct slb_shadow * __init new_slb_shadow(int cpu, unsigned long limit)
|
|||
struct paca_struct **paca_ptrs __read_mostly;
|
||||
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
|
||||
new_paca->lppaca_ptr = NULL;
|
||||
|
@ -163,7 +163,7 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu)
|
|||
}
|
||||
|
||||
/* 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 */
|
||||
local_paca = new_paca;
|
||||
|
@ -172,11 +172,15 @@ void setup_paca(struct paca_struct *new_paca)
|
|||
/* On Book3E, initialize the TLB miss exception frames */
|
||||
mtspr(SPRN_SPRG_TLB_EXFRAME, local_paca->extlb);
|
||||
#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
|
||||
* 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);
|
||||
#endif
|
||||
mtspr(SPRN_SPRG_PACA, local_paca);
|
||||
|
|
|
@ -8,6 +8,12 @@
|
|||
#ifndef __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 irqstack_early_init(void);
|
||||
|
||||
|
|
|
@ -284,24 +284,42 @@ void __init record_spr_defaults(void)
|
|||
* 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;
|
||||
|
||||
/* -------- printk is _NOT_ safe to use here ! ------- */
|
||||
|
||||
/* 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));
|
||||
|
||||
/* Assume we're on cpu 0 for now. Don't write to the paca yet! */
|
||||
/*
|
||||
* Assume we're on cpu 0 for now.
|
||||
*
|
||||
* We need to load a PACA very early for a few reasons.
|
||||
*
|
||||
* 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);
|
||||
setup_paca(&boot_paca);
|
||||
fixup_boot_paca();
|
||||
|
||||
/* -------- 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) */
|
||||
udbg_early_init();
|
||||
|
||||
|
|
|
@ -473,8 +473,10 @@ static long restore_tm_sigcontexts(struct task_struct *tsk,
|
|||
err |= __get_user(tsk->thread.ckpt_regs.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'. */
|
||||
err |= __get_user(regs->trap, &sc->gp_regs[PT_TRAP]);
|
||||
err |= __get_user(regs->dar, &sc->gp_regs[PT_DAR]);
|
||||
err |= __get_user(regs->dsisr, &sc->gp_regs[PT_DSISR]);
|
||||
err |= __get_user(regs->result, &sc->gp_regs[PT_RESULT]);
|
||||
|
|
|
@ -3620,6 +3620,7 @@ int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit,
|
|||
if (trap == BOOK3S_INTERRUPT_SYSCALL && !vcpu->arch.nested &&
|
||||
kvmppc_get_gpr(vcpu, 3) == H_CEDE) {
|
||||
kvmppc_nested_cede(vcpu);
|
||||
kvmppc_set_gpr(vcpu, 3, 0);
|
||||
trap = 0;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -397,7 +397,7 @@ _GLOBAL(set_context)
|
|||
* extern void loadcam_entry(unsigned int index)
|
||||
*
|
||||
* 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)
|
||||
mflr r5
|
||||
|
@ -433,6 +433,10 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS)
|
|||
*/
|
||||
_GLOBAL(loadcam_multi)
|
||||
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
|
||||
|
@ -458,6 +462,7 @@ _GLOBAL(loadcam_multi)
|
|||
mtmsr r6
|
||||
isync
|
||||
|
||||
10:
|
||||
mr r9,r3
|
||||
add r10,r3,r4
|
||||
2: bl loadcam_entry
|
||||
|
@ -466,6 +471,10 @@ _GLOBAL(loadcam_multi)
|
|||
mr r3,r9
|
||||
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 */
|
||||
mfmsr r6
|
||||
rlwinm. r6,r6,0,~(MSR_IS|MSR_DS)
|
||||
|
@ -481,6 +490,7 @@ _GLOBAL(loadcam_multi)
|
|||
tlbwe
|
||||
isync
|
||||
|
||||
3:
|
||||
mtlr r8
|
||||
blr
|
||||
#endif
|
||||
|
|
|
@ -294,23 +294,6 @@ static int __init maple_probe(void)
|
|||
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
|
||||
/*
|
||||
* Register a platform device for CPC925 memory controller on
|
||||
|
@ -367,3 +350,20 @@ static int __init maple_cpc925_edac_setup(void)
|
|||
}
|
||||
machine_device_initcall(maple, maple_cpc925_edac_setup);
|
||||
#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 *lmb, *start, *end;
|
||||
struct drmem_lmb *last_lmb;
|
||||
struct drmem_lmb *limit;
|
||||
|
||||
start = NULL;
|
||||
for_each_drmem_lmb(lmb) {
|
||||
|
@ -236,10 +236,10 @@ static int get_lmb_range(u32 drc_index, int n_lmbs,
|
|||
if (!start)
|
||||
return -EINVAL;
|
||||
|
||||
end = &start[n_lmbs - 1];
|
||||
end = &start[n_lmbs];
|
||||
|
||||
last_lmb = &drmem_info->lmbs[drmem_info->n_lmbs - 1];
|
||||
if (end > last_lmb)
|
||||
limit = &drmem_info->lmbs[drmem_info->n_lmbs];
|
||||
if (end > limit)
|
||||
return -EINVAL;
|
||||
|
||||
*start_lmb = start;
|
||||
|
|
|
@ -1255,7 +1255,7 @@ static int __init vpa_debugfs_init(void)
|
|||
{
|
||||
char name[16];
|
||||
long i;
|
||||
static struct dentry *vpa_dir;
|
||||
struct dentry *vpa_dir;
|
||||
|
||||
if (!firmware_has_feature(FW_FEATURE_SPLPAR))
|
||||
return 0;
|
||||
|
|
|
@ -68,13 +68,6 @@ static u32 xive_ipi_irq;
|
|||
/* Xive state for each 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 */
|
||||
#define XIVE_INVALID_TARGET (-1)
|
||||
|
||||
|
@ -1115,7 +1108,7 @@ static int xive_setup_cpu_ipi(unsigned int cpu)
|
|||
xc = per_cpu(xive_cpu, cpu);
|
||||
|
||||
/* Check if we are already setup */
|
||||
if (xc->hw_ipi != 0)
|
||||
if (xc->hw_ipi != XIVE_BAD_IRQ)
|
||||
return 0;
|
||||
|
||||
/* Grab an IPI from the backend, this will populate xc->hw_ipi */
|
||||
|
@ -1152,7 +1145,7 @@ static void xive_cleanup_cpu_ipi(unsigned int cpu, struct xive_cpu *xc)
|
|||
/* Disable the IPI and free the IRQ data */
|
||||
|
||||
/* Already cleaned up ? */
|
||||
if (xc->hw_ipi == 0)
|
||||
if (xc->hw_ipi == XIVE_BAD_IRQ)
|
||||
return;
|
||||
|
||||
/* Mask the IPI */
|
||||
|
@ -1308,6 +1301,7 @@ static int xive_prepare_cpu(unsigned int cpu)
|
|||
if (np)
|
||||
xc->chip_id = of_get_ibm_chip_id(np);
|
||||
of_node_put(np);
|
||||
xc->hw_ipi = XIVE_BAD_IRQ;
|
||||
|
||||
per_cpu(xive_cpu, cpu) = xc;
|
||||
}
|
||||
|
|
|
@ -298,7 +298,7 @@ static void xive_native_put_ipi(unsigned int cpu, struct xive_cpu *xc)
|
|||
s64 rc;
|
||||
|
||||
/* Free the IPI */
|
||||
if (!xc->hw_ipi)
|
||||
if (xc->hw_ipi == XIVE_BAD_IRQ)
|
||||
return;
|
||||
for (;;) {
|
||||
rc = opal_xive_free_irq(xc->hw_ipi);
|
||||
|
@ -306,7 +306,7 @@ static void xive_native_put_ipi(unsigned int cpu, struct xive_cpu *xc)
|
|||
msleep(OPAL_BUSY_DELAY_MS);
|
||||
continue;
|
||||
}
|
||||
xc->hw_ipi = 0;
|
||||
xc->hw_ipi = XIVE_BAD_IRQ;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -506,11 +506,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)
|
||||
{
|
||||
if (!xc->hw_ipi)
|
||||
if (xc->hw_ipi == XIVE_BAD_IRQ)
|
||||
return;
|
||||
|
||||
xive_irq_bitmap_free(xc->hw_ipi);
|
||||
xc->hw_ipi = 0;
|
||||
xc->hw_ipi = XIVE_BAD_IRQ;
|
||||
}
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
|
|
|
@ -5,6 +5,13 @@
|
|||
#ifndef __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 */
|
||||
struct xive_cpu {
|
||||
#ifdef CONFIG_SMP
|
||||
|
|
|
@ -101,7 +101,7 @@ void __init setup_bootmem(void)
|
|||
phys_addr_t vmlinux_end = __pa(_end);
|
||||
phys_addr_t end = reg->base + reg->size;
|
||||
|
||||
if (reg->base <= vmlinux_start && vmlinux_end <= end) {
|
||||
if (reg->base <= vmlinux_end && vmlinux_end <= end) {
|
||||
/*
|
||||
* Reserve from the start of the region to the end of
|
||||
* the kernel
|
||||
|
|
|
@ -141,7 +141,9 @@ struct lowcore {
|
|||
|
||||
/* br %r1 trampoline */
|
||||
__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
|
||||
|
|
|
@ -161,6 +161,7 @@ typedef struct thread_struct thread_struct;
|
|||
#define INIT_THREAD { \
|
||||
.ksp = sizeof(init_stack) + (unsigned long) &init_stack, \
|
||||
.fpu.regs = (void *) init_task.thread.fpu.fprs, \
|
||||
.last_break = 1, \
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <linux/const.h>
|
||||
#include <uapi/asm/setup.h>
|
||||
#include <linux/build_bug.h>
|
||||
|
||||
#define EP_OFFSET 0x10008
|
||||
#define EP_STRING "S390EP"
|
||||
|
@ -153,6 +154,12 @@ static inline unsigned long kaslr_offset(void)
|
|||
return __kaslr_offset;
|
||||
}
|
||||
|
||||
static inline u32 gen_lpswe(unsigned long addr)
|
||||
{
|
||||
BUILD_BUG_ON(addr > 0xfff);
|
||||
return 0xb2b20000 | addr;
|
||||
}
|
||||
|
||||
#else /* __ASSEMBLY__ */
|
||||
|
||||
#define IPL_DEVICE (IPL_DEVICE_OFFSET)
|
||||
|
|
|
@ -125,6 +125,8 @@ int main(void)
|
|||
OFFSET(__LC_EXT_DAMAGE_CODE, lowcore, external_damage_code);
|
||||
OFFSET(__LC_MCCK_FAIL_STOR_ADDR, lowcore, failing_storage_address);
|
||||
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_EXT_OLD_PSW, lowcore, external_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)
|
||||
{
|
||||
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)
|
||||
|
|
|
@ -115,26 +115,29 @@ _LPP_OFFSET = __LC_LPP
|
|||
|
||||
.macro SWITCH_ASYNC savearea,timer
|
||||
tmhh %r8,0x0001 # interrupting from user ?
|
||||
jnz 1f
|
||||
jnz 2f
|
||||
lgr %r14,%r9
|
||||
cghi %r14,__LC_RETURN_LPSWE
|
||||
je 0f
|
||||
slg %r14,BASED(.Lcritical_start)
|
||||
clg %r14,BASED(.Lcritical_length)
|
||||
jhe 0f
|
||||
jhe 1f
|
||||
0:
|
||||
lghi %r11,\savearea # inside critical section, do cleanup
|
||||
brasl %r14,cleanup_critical
|
||||
tmhh %r8,0x0001 # retest problem state after cleanup
|
||||
jnz 1f
|
||||
0: lg %r14,__LC_ASYNC_STACK # are we already on the target stack?
|
||||
jnz 2f
|
||||
1: lg %r14,__LC_ASYNC_STACK # are we already on the target stack?
|
||||
slgr %r14,%r15
|
||||
srag %r14,%r14,STACK_SHIFT
|
||||
jnz 2f
|
||||
jnz 3f
|
||||
CHECK_STACK \savearea
|
||||
aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
|
||||
j 3f
|
||||
1: UPDATE_VTIME %r14,%r15,\timer
|
||||
j 4f
|
||||
2: UPDATE_VTIME %r14,%r15,\timer
|
||||
BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
|
||||
2: lg %r15,__LC_ASYNC_STACK # load async stack
|
||||
3: la %r11,STACK_FRAME_OVERHEAD(%r15)
|
||||
3: lg %r15,__LC_ASYNC_STACK # load async stack
|
||||
4: la %r11,STACK_FRAME_OVERHEAD(%r15)
|
||||
.endm
|
||||
|
||||
.macro UPDATE_VTIME w1,w2,enter_timer
|
||||
|
@ -401,7 +404,7 @@ ENTRY(system_call)
|
|||
stpt __LC_EXIT_TIMER
|
||||
mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
|
||||
lmg %r11,%r15,__PT_R11(%r11)
|
||||
lpswe __LC_RETURN_PSW
|
||||
b __LC_RETURN_LPSWE(%r0)
|
||||
.Lsysc_done:
|
||||
|
||||
#
|
||||
|
@ -608,43 +611,50 @@ ENTRY(pgm_check_handler)
|
|||
BPOFF
|
||||
stmg %r8,%r15,__LC_SAVE_AREA_SYNC
|
||||
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
|
||||
larl %r13,cleanup_critical
|
||||
lmg %r8,%r9,__LC_PGM_OLD_PSW
|
||||
tmhh %r8,0x0001 # test problem state bit
|
||||
jnz 2f # -> fault in user space
|
||||
jnz 3f # -> fault in user space
|
||||
#if IS_ENABLED(CONFIG_KVM)
|
||||
# cleanup critical section for program checks in sie64a
|
||||
lgr %r14,%r9
|
||||
slg %r14,BASED(.Lsie_critical_start)
|
||||
clg %r14,BASED(.Lsie_critical_length)
|
||||
jhe 0f
|
||||
jhe 1f
|
||||
lg %r14,__SF_SIE_CONTROL(%r15) # get control block pointer
|
||||
ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE
|
||||
lctlg %c1,%c1,__LC_USER_ASCE # load primary asce
|
||||
larl %r9,sie_exit # skip forward to sie_exit
|
||||
lghi %r11,_PIF_GUEST_FAULT
|
||||
#endif
|
||||
0: tmhh %r8,0x4000 # PER bit set in old PSW ?
|
||||
jnz 1f # -> enabled, can't be a double fault
|
||||
1: tmhh %r8,0x4000 # PER bit set in old PSW ?
|
||||
jnz 2f # -> enabled, can't be a double fault
|
||||
tm __LC_PGM_ILC+3,0x80 # check for per exception
|
||||
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)
|
||||
# CHECK_VMAP_STACK branches to stack_overflow or 4f
|
||||
CHECK_VMAP_STACK __LC_SAVE_AREA_SYNC,4f
|
||||
2: UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER
|
||||
# CHECK_VMAP_STACK branches to stack_overflow or 5f
|
||||
CHECK_VMAP_STACK __LC_SAVE_AREA_SYNC,5f
|
||||
3: UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER
|
||||
BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
|
||||
lg %r15,__LC_KERNEL_STACK
|
||||
lgr %r14,%r12
|
||||
aghi %r14,__TASK_thread # pointer to thread_struct
|
||||
lghi %r13,__LC_PGM_TDB
|
||||
tm __LC_PGM_ILC+2,0x02 # check for transaction abort
|
||||
jz 3f
|
||||
jz 4f
|
||||
mvc __THREAD_trap_tdb(256,%r14),0(%r13)
|
||||
3: stg %r10,__THREAD_last_break(%r14)
|
||||
4: lgr %r13,%r11
|
||||
4: stg %r10,__THREAD_last_break(%r14)
|
||||
5: lgr %r13,%r11
|
||||
la %r11,STACK_FRAME_OVERHEAD(%r15)
|
||||
stmg %r0,%r7,__PT_R0(%r11)
|
||||
# clear user controlled registers to prevent speculative use
|
||||
|
@ -663,14 +673,14 @@ ENTRY(pgm_check_handler)
|
|||
stg %r13,__PT_FLAGS(%r11)
|
||||
stg %r10,__PT_ARGS(%r11)
|
||||
tm __LC_PGM_ILC+3,0x80 # check for per exception
|
||||
jz 5f
|
||||
jz 6f
|
||||
tmhh %r8,0x0001 # kernel per event ?
|
||||
jz .Lpgm_kprobe
|
||||
oi __PT_FLAGS+7(%r11),_PIF_PER_TRAP
|
||||
mvc __THREAD_per_address(8,%r14),__LC_PER_ADDRESS
|
||||
mvc __THREAD_per_cause(2,%r14),__LC_PER_CODE
|
||||
mvc __THREAD_per_paid(1,%r14),__LC_PER_ACCESS_ID
|
||||
5: REENABLE_IRQS
|
||||
6: REENABLE_IRQS
|
||||
xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
|
||||
larl %r1,pgm_check_table
|
||||
llgh %r10,__PT_INT_CODE+2(%r11)
|
||||
|
@ -775,7 +785,7 @@ ENTRY(io_int_handler)
|
|||
mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
|
||||
.Lio_exit_kernel:
|
||||
lmg %r11,%r15,__PT_R11(%r11)
|
||||
lpswe __LC_RETURN_PSW
|
||||
b __LC_RETURN_LPSWE(%r0)
|
||||
.Lio_done:
|
||||
|
||||
#
|
||||
|
@ -1216,7 +1226,7 @@ ENTRY(mcck_int_handler)
|
|||
stpt __LC_EXIT_TIMER
|
||||
mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
|
||||
0: lmg %r11,%r15,__PT_R11(%r11)
|
||||
lpswe __LC_RETURN_MCCK_PSW
|
||||
b __LC_RETURN_MCCK_LPSWE
|
||||
|
||||
.Lmcck_panic:
|
||||
lg %r15,__LC_NODAT_STACK
|
||||
|
@ -1273,6 +1283,8 @@ ENDPROC(stack_overflow)
|
|||
#endif
|
||||
|
||||
ENTRY(cleanup_critical)
|
||||
cghi %r9,__LC_RETURN_LPSWE
|
||||
je .Lcleanup_lpswe
|
||||
#if IS_ENABLED(CONFIG_KVM)
|
||||
clg %r9,BASED(.Lcleanup_table_sie) # .Lsie_gmap
|
||||
jl 0f
|
||||
|
@ -1426,6 +1438,7 @@ ENDPROC(cleanup_critical)
|
|||
mvc __LC_RETURN_PSW(16),__PT_PSW(%r9)
|
||||
mvc 0(64,%r11),__PT_R8(%r9)
|
||||
lmg %r0,%r7,__PT_R0(%r9)
|
||||
.Lcleanup_lpswe:
|
||||
1: lmg %r8,%r9,__LC_RETURN_PSW
|
||||
BR_EX %r14,%r11
|
||||
.Lcleanup_sysc_restore_insn:
|
||||
|
|
|
@ -105,6 +105,7 @@ int copy_thread_tls(unsigned long clone_flags, unsigned long new_stackp,
|
|||
p->thread.system_timer = 0;
|
||||
p->thread.hardirq_timer = 0;
|
||||
p->thread.softirq_timer = 0;
|
||||
p->thread.last_break = 1;
|
||||
|
||||
frame->sf.back_chain = 0;
|
||||
/* new return point is ret_from_fork */
|
||||
|
|
|
@ -158,8 +158,9 @@ static void show_cpu_mhz(struct seq_file *m, unsigned long n)
|
|||
static int show_cpuinfo(struct seq_file *m, void *v)
|
||||
{
|
||||
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);
|
||||
if (!machine_has_cpu_mhz)
|
||||
return 0;
|
||||
|
@ -172,6 +173,8 @@ static inline void *c_update(loff_t *pos)
|
|||
{
|
||||
if (*pos)
|
||||
*pos = cpumask_next(*pos - 1, cpu_online_mask);
|
||||
else
|
||||
*pos = cpumask_first(cpu_online_mask);
|
||||
return *pos < nr_cpu_ids ? (void *)*pos + 1 : NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -73,6 +73,7 @@
|
|||
#include <asm/nospec-branch.h>
|
||||
#include <asm/mem_detect.h>
|
||||
#include <asm/uv.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include "entry.h"
|
||||
|
||||
/*
|
||||
|
@ -467,6 +468,8 @@ static void __init setup_lowcore_dat_off(void)
|
|||
arch_spin_lock_setup(0);
|
||||
#endif
|
||||
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);
|
||||
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_index = 0;
|
||||
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))
|
||||
goto out_async;
|
||||
if (vdso_alloc_per_cpu(lc))
|
||||
|
|
|
@ -1202,6 +1202,7 @@ static int vsie_run(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
|
|||
scb_s->iprcc = PGM_ADDRESSING;
|
||||
scb_s->pgmilc = 4;
|
||||
scb_s->gpsw.addr = __rewind_psw(scb_s->gpsw, 4);
|
||||
rc = 1;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
unsigned long gaddr, int level)
|
||||
{
|
||||
const int asce_type = gmap->asce & _ASCE_TYPE_MASK;
|
||||
unsigned long *table;
|
||||
|
||||
if ((gmap->asce & _ASCE_TYPE_MASK) + 4 < (level * 4))
|
||||
return NULL;
|
||||
if (gmap_is_shadow(gmap) && gmap->removed)
|
||||
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;
|
||||
|
||||
table = gmap->table;
|
||||
switch (gmap->asce & _ASCE_TYPE_MASK) {
|
||||
case _ASCE_TYPE_REGION1:
|
||||
|
@ -1840,6 +1844,7 @@ int gmap_shadow_r3t(struct gmap *sg, unsigned long saddr, unsigned long r3t,
|
|||
goto out_free;
|
||||
} else if (*table & _REGION_ENTRY_ORIGIN) {
|
||||
rc = -EAGAIN; /* Race with shadow */
|
||||
goto out_free;
|
||||
}
|
||||
crst_table_init(s_r3t, _REGION3_ENTRY_EMPTY);
|
||||
/* mark as invalid as long as the parent table is not protected */
|
||||
|
|
|
@ -415,6 +415,10 @@ void __init vmem_map_init(void)
|
|||
SET_MEMORY_RO | SET_MEMORY_X);
|
||||
__set_memory(__stext_dma, (__etext_dma - __stext_dma) >> PAGE_SHIFT,
|
||||
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",
|
||||
(unsigned long)(__end_rodata - _stext) >> 10);
|
||||
}
|
||||
|
|
|
@ -309,14 +309,13 @@ out:
|
|||
|
||||
int clp_disable_fh(struct zpci_dev *zdev)
|
||||
{
|
||||
u32 fh = zdev->fh;
|
||||
int rc;
|
||||
|
||||
if (!zdev_enabled(zdev))
|
||||
return 0;
|
||||
|
||||
rc = clp_set_pci_fn(zdev, 0, CLP_SET_DISABLE_PCI_FN);
|
||||
zpci_dbg(3, "dis fid:%x, fh:%x, rc:%d\n", zdev->fid, fh, rc);
|
||||
zpci_dbg(3, "dis fid:%x, fh:%x, rc:%d\n", zdev->fid, zdev->fh, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
@ -1606,7 +1606,9 @@ int io_thread(void *arg)
|
|||
written = 0;
|
||||
|
||||
do {
|
||||
res = os_write_file(kernel_fd, ((char *) io_req_buffer) + written, n);
|
||||
res = os_write_file(kernel_fd,
|
||||
((char *) io_req_buffer) + written,
|
||||
n - written);
|
||||
if (res >= 0) {
|
||||
written += res;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <linux/falloc.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/socket.h>
|
||||
|
|
|
@ -106,7 +106,7 @@ ENTRY(startup_32)
|
|||
notl %eax
|
||||
andl %eax, %ebx
|
||||
cmpl $LOAD_PHYSICAL_ADDR, %ebx
|
||||
jge 1f
|
||||
jae 1f
|
||||
#endif
|
||||
movl $LOAD_PHYSICAL_ADDR, %ebx
|
||||
1:
|
||||
|
|
|
@ -106,7 +106,7 @@ ENTRY(startup_32)
|
|||
notl %eax
|
||||
andl %eax, %ebx
|
||||
cmpl $LOAD_PHYSICAL_ADDR, %ebx
|
||||
jge 1f
|
||||
jae 1f
|
||||
#endif
|
||||
movl $LOAD_PHYSICAL_ADDR, %ebx
|
||||
1:
|
||||
|
@ -297,7 +297,7 @@ ENTRY(startup_64)
|
|||
notq %rax
|
||||
andq %rax, %rbp
|
||||
cmpq $LOAD_PHYSICAL_ADDR, %rbp
|
||||
jge 1f
|
||||
jae 1f
|
||||
#endif
|
||||
movq $LOAD_PHYSICAL_ADDR, %rbp
|
||||
1:
|
||||
|
|
|
@ -1647,6 +1647,7 @@ ENTRY(int3)
|
|||
END(int3)
|
||||
|
||||
ENTRY(general_protection)
|
||||
ASM_CLAC
|
||||
pushl $do_general_protection
|
||||
jmp common_exception
|
||||
END(general_protection)
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <linux/clockchips.h>
|
||||
#include <linux/hyperv.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/cpuhotplug.h>
|
||||
|
||||
#ifdef CONFIG_HYPERV_TSCPAGE
|
||||
|
@ -427,11 +428,14 @@ void hyperv_cleanup(void)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(hyperv_cleanup);
|
||||
|
||||
void hyperv_report_panic(struct pt_regs *regs, long err)
|
||||
void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die)
|
||||
{
|
||||
static bool panic_reported;
|
||||
u64 guest_id;
|
||||
|
||||
if (in_die && !panic_on_oops)
|
||||
return;
|
||||
|
||||
/*
|
||||
* We prefer to report panic on 'die' chain as we have proper
|
||||
* registers to report, but if we miss it (e.g. on BUG()) we need
|
||||
|
|
|
@ -53,7 +53,7 @@ extern int apic_verbosity;
|
|||
extern int local_apic_timer_c2_ok;
|
||||
|
||||
extern int disable_apic;
|
||||
extern unsigned int lapic_timer_frequency;
|
||||
extern unsigned int lapic_timer_period;
|
||||
|
||||
extern enum apic_intr_mode_id apic_intr_mode;
|
||||
enum apic_intr_mode_id {
|
||||
|
|
|
@ -1127,7 +1127,7 @@ struct kvm_x86_ops {
|
|||
bool (*pt_supported)(void);
|
||||
bool (*pku_supported)(void);
|
||||
|
||||
int (*check_nested_events)(struct kvm_vcpu *vcpu, bool external_intr);
|
||||
int (*check_nested_events)(struct kvm_vcpu *vcpu);
|
||||
void (*request_immediate_exit)(struct kvm_vcpu *vcpu);
|
||||
|
||||
void (*sched_in)(struct kvm_vcpu *kvm, int cpu);
|
||||
|
|
|
@ -41,7 +41,7 @@ struct microcode_amd {
|
|||
unsigned int mpb[0];
|
||||
};
|
||||
|
||||
#define PATCH_MAX_SIZE PAGE_SIZE
|
||||
#define PATCH_MAX_SIZE (3 * PAGE_SIZE)
|
||||
|
||||
#ifdef CONFIG_MICROCODE_AMD
|
||||
extern void __init load_ucode_amd_bsp(unsigned int family);
|
||||
|
|
|
@ -343,7 +343,7 @@ static inline int cpumask_to_vpset(struct hv_vpset *vpset,
|
|||
|
||||
void __init hyperv_init(void);
|
||||
void hyperv_setup_mmu_ops(void);
|
||||
void hyperv_report_panic(struct pt_regs *regs, long err);
|
||||
void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die);
|
||||
void hyperv_report_panic_msg(phys_addr_t pa, size_t size);
|
||||
bool hv_is_hyperv_initialized(void);
|
||||
void hyperv_cleanup(void);
|
||||
|
|
|
@ -624,12 +624,15 @@ static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
|
|||
return __pmd(val);
|
||||
}
|
||||
|
||||
/* mprotect needs to preserve PAT bits when updating vm_page_prot */
|
||||
/*
|
||||
* mprotect needs to preserve PAT and encryption bits when updating
|
||||
* vm_page_prot
|
||||
*/
|
||||
#define pgprot_modify pgprot_modify
|
||||
static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
|
||||
{
|
||||
pgprotval_t preservebits = pgprot_val(oldprot) & _PAGE_CHG_MASK;
|
||||
pgprotval_t addbits = pgprot_val(newprot);
|
||||
pgprotval_t addbits = pgprot_val(newprot) & ~_PAGE_CHG_MASK;
|
||||
return __pgprot(preservebits | addbits);
|
||||
}
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@
|
|||
*/
|
||||
#define _PAGE_CHG_MASK (PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT | \
|
||||
_PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY | \
|
||||
_PAGE_SOFT_DIRTY | _PAGE_DEVMAP)
|
||||
_PAGE_SOFT_DIRTY | _PAGE_DEVMAP | _PAGE_ENC)
|
||||
#define _HPAGE_CHG_MASK (_PAGE_CHG_MASK | _PAGE_PSE)
|
||||
|
||||
/*
|
||||
|
|
|
@ -2,8 +2,15 @@
|
|||
#ifndef _UAPI_ASM_X86_UNISTD_H
|
||||
#define _UAPI_ASM_X86_UNISTD_H
|
||||
|
||||
/* x32 syscall flag bit */
|
||||
#define __X32_SYSCALL_BIT 0x40000000UL
|
||||
/*
|
||||
* x32 syscall flag bit. Some user programs expect syscall NR macros
|
||||
* and __X32_SYSCALL_BIT to have type int, even though syscall numbers
|
||||
* are, for practical purposes, unsigned long.
|
||||
*
|
||||
* Fortunately, expressions like (nr & ~__X32_SYSCALL_BIT) do the right
|
||||
* thing regardless.
|
||||
*/
|
||||
#define __X32_SYSCALL_BIT 0x40000000
|
||||
|
||||
#ifndef __KERNEL__
|
||||
# ifdef __i386__
|
||||
|
|
|
@ -1740,7 +1740,7 @@ int __acpi_acquire_global_lock(unsigned int *lock)
|
|||
new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1));
|
||||
val = cmpxchg(lock, old, new);
|
||||
} while (unlikely (val != old));
|
||||
return (new < 3) ? -1 : 0;
|
||||
return ((new & 0x3) < 3) ? -1 : 0;
|
||||
}
|
||||
|
||||
int __acpi_release_global_lock(unsigned int *lock)
|
||||
|
|
|
@ -146,7 +146,8 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu,
|
|||
|
||||
/* Make sure we are running on right CPU */
|
||||
|
||||
retval = work_on_cpu(cpu, acpi_processor_ffh_cstate_probe_cpu, cx);
|
||||
retval = call_on_cpu(cpu, acpi_processor_ffh_cstate_probe_cpu, cx,
|
||||
false);
|
||||
if (retval == 0) {
|
||||
/* Use the hint in CST */
|
||||
percpu_entry->states[cx->index].eax = cx->address;
|
||||
|
|
|
@ -195,7 +195,7 @@ static struct resource lapic_resource = {
|
|||
.flags = IORESOURCE_MEM | IORESOURCE_BUSY,
|
||||
};
|
||||
|
||||
unsigned int lapic_timer_frequency = 0;
|
||||
unsigned int lapic_timer_period = 0;
|
||||
|
||||
static void apic_pm_activate(void);
|
||||
|
||||
|
@ -501,7 +501,7 @@ lapic_timer_set_periodic_oneshot(struct clock_event_device *evt, bool oneshot)
|
|||
if (evt->features & CLOCK_EVT_FEAT_DUMMY)
|
||||
return 0;
|
||||
|
||||
__setup_APIC_LVTT(lapic_timer_frequency, oneshot, 1);
|
||||
__setup_APIC_LVTT(lapic_timer_period, oneshot, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -805,11 +805,11 @@ calibrate_by_pmtimer(long deltapm, long *delta, long *deltatsc)
|
|||
|
||||
static int __init lapic_init_clockevent(void)
|
||||
{
|
||||
if (!lapic_timer_frequency)
|
||||
if (!lapic_timer_period)
|
||||
return -1;
|
||||
|
||||
/* Calculate the scaled math multiplication factor */
|
||||
lapic_clockevent.mult = div_sc(lapic_timer_frequency/APIC_DIVISOR,
|
||||
lapic_clockevent.mult = div_sc(lapic_timer_period/APIC_DIVISOR,
|
||||
TICK_NSEC, lapic_clockevent.shift);
|
||||
lapic_clockevent.max_delta_ns =
|
||||
clockevent_delta2ns(0x7FFFFFFF, &lapic_clockevent);
|
||||
|
@ -840,7 +840,7 @@ static int __init calibrate_APIC_clock(void)
|
|||
*/
|
||||
if (!lapic_init_clockevent()) {
|
||||
apic_printk(APIC_VERBOSE, "lapic timer already calibrated %d\n",
|
||||
lapic_timer_frequency);
|
||||
lapic_timer_period);
|
||||
/*
|
||||
* Direct calibration methods must have an always running
|
||||
* local APIC timer, no need for broadcast timer.
|
||||
|
@ -921,13 +921,13 @@ static int __init calibrate_APIC_clock(void)
|
|||
pm_referenced = !calibrate_by_pmtimer(lapic_cal_pm2 - lapic_cal_pm1,
|
||||
&delta, &deltatsc);
|
||||
|
||||
lapic_timer_frequency = (delta * APIC_DIVISOR) / LAPIC_CAL_LOOPS;
|
||||
lapic_timer_period = (delta * APIC_DIVISOR) / LAPIC_CAL_LOOPS;
|
||||
lapic_init_clockevent();
|
||||
|
||||
apic_printk(APIC_VERBOSE, "..... delta %ld\n", delta);
|
||||
apic_printk(APIC_VERBOSE, "..... mult: %u\n", lapic_clockevent.mult);
|
||||
apic_printk(APIC_VERBOSE, "..... calibration result: %u\n",
|
||||
lapic_timer_frequency);
|
||||
lapic_timer_period);
|
||||
|
||||
if (boot_cpu_has(X86_FEATURE_TSC)) {
|
||||
apic_printk(APIC_VERBOSE, "..... CPU clock speed is "
|
||||
|
@ -938,13 +938,13 @@ static int __init calibrate_APIC_clock(void)
|
|||
|
||||
apic_printk(APIC_VERBOSE, "..... host bus clock speed is "
|
||||
"%u.%04u MHz.\n",
|
||||
lapic_timer_frequency / (1000000 / HZ),
|
||||
lapic_timer_frequency % (1000000 / HZ));
|
||||
lapic_timer_period / (1000000 / HZ),
|
||||
lapic_timer_period % (1000000 / HZ));
|
||||
|
||||
/*
|
||||
* Do a sanity check on the APIC calibration result
|
||||
*/
|
||||
if (lapic_timer_frequency < (1000000 / HZ)) {
|
||||
if (lapic_timer_period < (1000000 / HZ)) {
|
||||
local_irq_enable();
|
||||
pr_warning("APIC frequency too slow, disabling apic timer\n");
|
||||
return -1;
|
||||
|
|
|
@ -66,6 +66,32 @@ void check_mpx_erratum(struct cpuinfo_x86 *c)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Processors which have self-snooping capability can handle conflicting
|
||||
* memory type across CPUs by snooping its own cache. However, there exists
|
||||
* CPU models in which having conflicting memory types still leads to
|
||||
* unpredictable behavior, machine check errors, or hangs. Clear this
|
||||
* feature to prevent its use on machines with known erratas.
|
||||
*/
|
||||
static void check_memory_type_self_snoop_errata(struct cpuinfo_x86 *c)
|
||||
{
|
||||
switch (c->x86_model) {
|
||||
case INTEL_FAM6_CORE_YONAH:
|
||||
case INTEL_FAM6_CORE2_MEROM:
|
||||
case INTEL_FAM6_CORE2_MEROM_L:
|
||||
case INTEL_FAM6_CORE2_PENRYN:
|
||||
case INTEL_FAM6_CORE2_DUNNINGTON:
|
||||
case INTEL_FAM6_NEHALEM:
|
||||
case INTEL_FAM6_NEHALEM_G:
|
||||
case INTEL_FAM6_NEHALEM_EP:
|
||||
case INTEL_FAM6_NEHALEM_EX:
|
||||
case INTEL_FAM6_WESTMERE:
|
||||
case INTEL_FAM6_WESTMERE_EP:
|
||||
case INTEL_FAM6_SANDYBRIDGE:
|
||||
setup_clear_cpu_cap(X86_FEATURE_SELFSNOOP);
|
||||
}
|
||||
}
|
||||
|
||||
static bool ring3mwait_disabled __read_mostly;
|
||||
|
||||
static int __init ring3mwait_disable(char *__unused)
|
||||
|
@ -239,9 +265,9 @@ static void early_init_intel(struct cpuinfo_x86 *c)
|
|||
/* Penwell and Cloverview have the TSC which doesn't sleep on S3 */
|
||||
if (c->x86 == 6) {
|
||||
switch (c->x86_model) {
|
||||
case 0x27: /* Penwell */
|
||||
case 0x35: /* Cloverview */
|
||||
case 0x4a: /* Merrifield */
|
||||
case INTEL_FAM6_ATOM_SALTWELL_MID:
|
||||
case INTEL_FAM6_ATOM_SALTWELL_TABLET:
|
||||
case INTEL_FAM6_ATOM_SILVERMONT_MID:
|
||||
set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC_S3);
|
||||
break;
|
||||
default:
|
||||
|
@ -304,6 +330,7 @@ static void early_init_intel(struct cpuinfo_x86 *c)
|
|||
}
|
||||
|
||||
check_mpx_erratum(c);
|
||||
check_memory_type_self_snoop_errata(c);
|
||||
|
||||
/*
|
||||
* Get the number of SMT siblings early from the extended topology
|
||||
|
|
|
@ -256,6 +256,16 @@ static void __init ms_hyperv_init_platform(void)
|
|||
cpuid_eax(HYPERV_CPUID_NESTED_FEATURES);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hyper-V expects to get crash register data or kmsg when
|
||||
* crash enlightment is available and system crashes. Set
|
||||
* crash_kexec_post_notifiers to be true to make sure that
|
||||
* calling crash enlightment interface before running kdump
|
||||
* kernel.
|
||||
*/
|
||||
if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE)
|
||||
crash_kexec_post_notifiers = true;
|
||||
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
if (ms_hyperv.features & HV_X64_ACCESS_FREQUENCY_MSRS &&
|
||||
ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) {
|
||||
|
@ -266,9 +276,9 @@ static void __init ms_hyperv_init_platform(void)
|
|||
|
||||
rdmsrl(HV_X64_MSR_APIC_FREQUENCY, hv_lapic_frequency);
|
||||
hv_lapic_frequency = div_u64(hv_lapic_frequency, HZ);
|
||||
lapic_timer_frequency = hv_lapic_frequency;
|
||||
lapic_timer_period = hv_lapic_frequency;
|
||||
pr_info("Hyper-V: LAPIC Timer Frequency: %#x\n",
|
||||
lapic_timer_frequency);
|
||||
lapic_timer_period);
|
||||
}
|
||||
|
||||
register_nmi_handler(NMI_UNKNOWN, hv_nmi_unknown, NMI_FLAG_FIRST,
|
||||
|
|
|
@ -578,6 +578,8 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r)
|
|||
d->id = id;
|
||||
cpumask_set_cpu(cpu, &d->cpu_mask);
|
||||
|
||||
rdt_domain_reconfigure_cdp(r);
|
||||
|
||||
if (r->alloc_capable && domain_setup_ctrlval(r, d)) {
|
||||
kfree(d);
|
||||
return;
|
||||
|
|
|
@ -601,5 +601,6 @@ bool has_busy_rmid(struct rdt_resource *r, struct rdt_domain *d);
|
|||
void __check_limbo(struct rdt_domain *d, bool force_free);
|
||||
bool cbm_validate_intel(char *buf, u32 *data, struct rdt_resource *r);
|
||||
bool cbm_validate_amd(char *buf, u32 *data, struct rdt_resource *r);
|
||||
void rdt_domain_reconfigure_cdp(struct rdt_resource *r);
|
||||
|
||||
#endif /* _ASM_X86_RESCTRL_INTERNAL_H */
|
||||
|
|
|
@ -1769,6 +1769,19 @@ static int set_cache_qos_cfg(int level, bool enable)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Restore the qos cfg state when a domain comes online */
|
||||
void rdt_domain_reconfigure_cdp(struct rdt_resource *r)
|
||||
{
|
||||
if (!r->alloc_capable)
|
||||
return;
|
||||
|
||||
if (r == &rdt_resources_all[RDT_RESOURCE_L2DATA])
|
||||
l2_qos_cfg_update(&r->alloc_enabled);
|
||||
|
||||
if (r == &rdt_resources_all[RDT_RESOURCE_L3DATA])
|
||||
l3_qos_cfg_update(&r->alloc_enabled);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable or disable the MBA software controller
|
||||
* which helps user specify bandwidth in MBps.
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user