Merge 21a6ab2131
("Merge tag 'modules-for-v5.12' of git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux") into android-mainline
Steps on the way to 5.12-rc1 Resolves conflicts in: include/linux/module.h Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I44772d65a5d6b1c5f4c33905554092c2cdc5b210
This commit is contained in:
commit
368ecbcb2f
|
@ -42,6 +42,7 @@
|
|||
*.so.dbg
|
||||
*.su
|
||||
*.symtypes
|
||||
*.symversions
|
||||
*.tab.[ch]
|
||||
*.tar
|
||||
*.xz
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
CSR SiRFatlas7 GPIO controller bindings
|
||||
|
||||
Required properties:
|
||||
- compatible : "sirf,atlas7-gpio"
|
||||
- reg : Address range of the pinctrl registers
|
||||
- interrupts : Interrupts used by every GPIO group
|
||||
- gpio-banks : How many gpio banks on this controller
|
||||
- gpio-controller : Indicates this device is a GPIO controller
|
||||
- interrupt-controller : Marks the device node as an interrupt controller
|
||||
|
||||
The GPIO controller also acts as an interrupt controller. It uses the default
|
||||
two cells specifier as described in Documentation/devicetree/bindings/
|
||||
interrupt-controller/interrupts.txt.
|
||||
|
||||
Example:
|
||||
|
||||
gpio_0: gpio_mediam@17040000 {
|
||||
compatible = "sirf,atlas7-gpio";
|
||||
reg = <0x17040000 0x1000>;
|
||||
interrupts = <0 13 0>, <0 14 0>;
|
||||
|
||||
#gpio-cells = <2>;
|
||||
#interrupt-cells = <2>;
|
||||
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
|
||||
gpio-banks = <2>;
|
||||
gpio-ranges = <&pinctrl 0 0 0>,
|
||||
<&pinctrl 32 0 0>;
|
||||
gpio-ranges-group-names = "lvds_gpio_grp",
|
||||
"uart_nand_gpio_grp";
|
||||
};
|
||||
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
led1 {
|
||||
gpios = <&gpio_1 15 0>;
|
||||
...
|
||||
};
|
||||
|
||||
led2 {
|
||||
gpios = <&gpio_2 34 0>;
|
||||
...
|
||||
};
|
||||
};
|
||||
|
||||
Please refer to gpio.txt in this directory for details of the common
|
||||
gpio properties used by devices.
|
|
@ -1,7 +0,0 @@
|
|||
ST-Ericsson COH 901 571/3 GPIO controller
|
||||
|
||||
Required properties:
|
||||
- compatible: Compatible property value should be "stericsson,gpio-coh901"
|
||||
- reg: Physical base address of the controller and length of memory mapped
|
||||
region.
|
||||
- interrupts: the 0...n interrupts assigned to the different GPIO ports/banks.
|
|
@ -53,6 +53,8 @@ properties:
|
|||
- allwinner,sun50i-h5-pinctrl
|
||||
- allwinner,sun50i-h6-pinctrl
|
||||
- allwinner,sun50i-h6-r-pinctrl
|
||||
- allwinner,sun50i-h616-pinctrl
|
||||
- allwinner,sun50i-h616-r-pinctrl
|
||||
- allwinner,suniv-f1c100s-pinctrl
|
||||
- nextthing,gr8-pinctrl
|
||||
|
||||
|
@ -61,7 +63,7 @@ properties:
|
|||
|
||||
interrupts:
|
||||
minItems: 1
|
||||
maxItems: 7
|
||||
maxItems: 8
|
||||
description:
|
||||
One interrupt per external interrupt bank supported on the
|
||||
controller, sorted by bank number ascending order.
|
||||
|
@ -91,7 +93,7 @@ properties:
|
|||
bank found in the controller
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 5
|
||||
maxItems: 8
|
||||
|
||||
patternProperties:
|
||||
# It's pretty scary, but the basic idea is that:
|
||||
|
@ -145,6 +147,17 @@ allOf:
|
|||
# boards are defining it at the moment so it would generate a lot of
|
||||
# warnings.
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- allwinner,sun50i-h616-pinctrl
|
||||
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
minItems: 8
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
|
|
|
@ -35,9 +35,11 @@ ioset settings. Use the macros from boot/dts/<soc>-pinfunc.h file to get the
|
|||
right representation of the pin.
|
||||
|
||||
Optional properties:
|
||||
- GENERIC_PINCONFIG: generic pinconfig options to use, bias-disable,
|
||||
bias-pull-down, bias-pull-up, drive-open-drain, input-schmitt-enable,
|
||||
input-debounce, output-low, output-high.
|
||||
- GENERIC_PINCONFIG: generic pinconfig options to use:
|
||||
- bias-disable, bias-pull-down, bias-pull-up, drive-open-drain,
|
||||
input-schmitt-enable, input-debounce, output-low, output-high.
|
||||
- for microchip,sama7g5-pinctrl only:
|
||||
- slew-rate: 0 - disabled, 1 - enabled (default)
|
||||
- atmel,drive-strength: 0 or 1 for low drive, 2 for medium drive and 3 for
|
||||
high drive. The default value is low drive.
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ For example:
|
|||
<0x660009b0 0x40>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&nand_sel &uart3_rx &sdio0_d4>;
|
||||
pinctrl-0 = <&nand_sel>, <&uart3_rx>, <&sdio0_d4>;
|
||||
|
||||
/* Select nand function */
|
||||
nand_sel: nand_sel {
|
||||
|
|
|
@ -30,7 +30,7 @@ For example:
|
|||
<0x1803f408 0x04>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pwm &gpio_b &nand_sel>;
|
||||
pinctrl-0 = <&pwm>, <&gpio_b>, <&nand_sel>;
|
||||
|
||||
pwm: pwm {
|
||||
function = "pwm";
|
||||
|
|
|
@ -60,7 +60,7 @@ iomuxc-lpsr controller and SDA pad from iomuxc controller as:
|
|||
|
||||
i2c1: i2c@30a20000 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_i2c1_1 &pinctrl_i2c1_2>;
|
||||
pinctrl-0 = <&pinctrl_i2c1_1>, <&pinctrl_i2c1_2>;
|
||||
};
|
||||
|
||||
iomuxc-lpsr@302c0000 {
|
||||
|
|
|
@ -99,8 +99,8 @@ patternProperties:
|
|||
|
||||
'#interrupt-cells':
|
||||
description:
|
||||
Specifies the pin (port and bit) and flags, as defined in
|
||||
defined in include/dt-bindings/interrupt-controller/irq.h
|
||||
Specifies the pin (port and bit) and flags, as defined in
|
||||
defined in include/dt-bindings/interrupt-controller/irq.h
|
||||
const: 3
|
||||
|
||||
ngpios:
|
||||
|
|
|
@ -1,109 +0,0 @@
|
|||
CSR SiRFatlas7 pinmux controller
|
||||
|
||||
Required properties:
|
||||
- compatible : "sirf,atlas7-ioc"
|
||||
- reg : Address range of the pinctrl registers
|
||||
|
||||
For example, pinctrl might have properties like the following:
|
||||
pinctrl: ioc@18880000 {
|
||||
compatible = "sirf,atlas7-ioc";
|
||||
reg = <0x18880000 0x1000>;
|
||||
|
||||
a_ac97_pmx: ac97@0 {
|
||||
ac97 {
|
||||
groups = "audio_ac97_grp";
|
||||
function = "audio_ac97";
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
|
||||
sd2_pmx: sd2@0 {
|
||||
sd2 {
|
||||
groups = "sd2_grp0";
|
||||
function = "sd2";
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
|
||||
|
||||
sample0_cfg: sample0@0 {
|
||||
sample0 {
|
||||
pins = "ldd_0", "ldd_1";
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
sample1_cfg: sample1@0 {
|
||||
sample1 {
|
||||
pins = "ldd_2", "ldd_3";
|
||||
input-schmitt-enable;
|
||||
};
|
||||
};
|
||||
|
||||
sample2_cfg: sample2@0 {
|
||||
sample2 {
|
||||
groups = "uart4_nopause_grp";
|
||||
bias-pull-down;
|
||||
};
|
||||
};
|
||||
|
||||
sample3_cfg: sample3@0 {
|
||||
sample3 {
|
||||
pins = "ldd_4", "ldd_5";
|
||||
drive-strength = <2>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
Please refer to pinctrl-bindings.txt in this directory for details of the common
|
||||
pinctrl bindings used by client devices.
|
||||
|
||||
SiRFatlas7's pinmux nodes act as a container for an arbitrary number of subnodes.
|
||||
Each of these subnodes represents some desired configuration for a group of pins.
|
||||
|
||||
Required subnode-properties:
|
||||
- groups : An array of strings. Each string contains the name of a group.
|
||||
- function: A string containing the name of the function to mux to the
|
||||
group.
|
||||
|
||||
Valid values for group and function names can be found from looking at the
|
||||
group and function arrays in driver files:
|
||||
drivers/pinctrl/pinctrl-sirf.c
|
||||
|
||||
For example, pinctrl might have subnodes like the following:
|
||||
sd0_pmx: sd0@0 {
|
||||
sd0 {
|
||||
groups = "sd0_grp";
|
||||
function = "sd0";
|
||||
};
|
||||
};
|
||||
|
||||
sd1_pmx0: sd1@0 {
|
||||
sd1 {
|
||||
groups = "sd1_grp0";
|
||||
function = "sd1_m0";
|
||||
};
|
||||
};
|
||||
|
||||
sd1_pmx1: sd1@1 {
|
||||
sd1 {
|
||||
groups = "sd1_grp1";
|
||||
function = "sd1_m1";
|
||||
};
|
||||
};
|
||||
|
||||
For a specific board, if it wants to use sd1,
|
||||
it can add the following to its board-specific .dts file.
|
||||
sd1: sd@12340000 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&sd1_pmx0>;
|
||||
}
|
||||
|
||||
or
|
||||
|
||||
sd1: sd@12340000 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&sd1_pmx1>;
|
||||
}
|
|
@ -77,13 +77,13 @@ For example:
|
|||
device {
|
||||
pinctrl-names = "active", "idle";
|
||||
pinctrl-0 = <&state_0_node_a>;
|
||||
pinctrl-1 = <&state_1_node_a &state_1_node_b>;
|
||||
pinctrl-1 = <&state_1_node_a>, <&state_1_node_b>;
|
||||
};
|
||||
|
||||
/* For the same device if using state IDs */
|
||||
device {
|
||||
pinctrl-0 = <&state_0_node_a>;
|
||||
pinctrl-1 = <&state_1_node_a &state_1_node_b>;
|
||||
pinctrl-1 = <&state_1_node_a>, <&state_1_node_b>;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -134,7 +134,7 @@ gpio21: gpio@21 {
|
|||
#interrupt-cells = <0x2>;
|
||||
microchip,irq-mirror;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&i2cgpio0irq &gpio21pullups>;
|
||||
pinctrl-0 = <&i2cgpio0irq>, <&gpio21pullups>;
|
||||
|
||||
gpio21pullups: pinmux {
|
||||
pins = "gpio0", "gpio1", "gpio2", "gpio3",
|
||||
|
|
|
@ -91,7 +91,7 @@ Examples:
|
|||
pinctrl@1c20800 {
|
||||
compatible = "mediatek,mt8135-pinctrl";
|
||||
reg = <0 0x1000B000 0 0x1000>;
|
||||
mediatek,pctl-regmap = <&syscfg_pctl_a &syscfg_pctl_b>;
|
||||
mediatek,pctl-regmap = <&syscfg_pctl_a>, <&syscfg_pctl_b>;
|
||||
pins-are-numbered;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
|
|
|
@ -8,7 +8,7 @@ Required properties:
|
|||
- reg : offset and length of the register set for the mux registers
|
||||
|
||||
- #pinctrl-cells : number of cells in addition to the index, set to 1
|
||||
for pinctrl-single,pins and 2 for pinctrl-single,bits
|
||||
or 2 for pinctrl-single,pins and set to 2 for pinctrl-single,bits
|
||||
|
||||
- pinctrl-single,register-width : pinmux register access width in bits
|
||||
|
||||
|
@ -80,7 +80,7 @@ Optional properties:
|
|||
property.
|
||||
|
||||
/* pin base, nr pins & gpio function */
|
||||
pinctrl-single,gpio-range = <&range 0 3 0 &range 3 9 1>;
|
||||
pinctrl-single,gpio-range = <&range 0 3 0>, <&range 3 9 1>;
|
||||
|
||||
- interrupt-controller : standard interrupt controller binding if using
|
||||
interrupts for wake-up events for example. In this case pinctrl-single
|
||||
|
@ -185,10 +185,10 @@ pmx_gpio: pinmux@d401e000 {
|
|||
pinctrl-single,function-mask = <7>;
|
||||
|
||||
/* sparse GPIO range could be supported */
|
||||
pinctrl-single,gpio-range = <&range 0 3 0 &range 3 9 1
|
||||
&range 12 1 0 &range 13 29 1
|
||||
&range 43 1 0 &range 44 49 1
|
||||
&range 94 1 1 &range 96 2 1>;
|
||||
pinctrl-single,gpio-range = <&range 0 3 0>, <&range 3 9 1>,
|
||||
<&range 12 1 0>, <&range 13 29 1>,
|
||||
<&range 43 1 0>, <&range 44 49 1>,
|
||||
<&range 94 1 1>, <&range 96 2 1>;
|
||||
|
||||
range: gpio-range {
|
||||
#pinctrl-single,gpio-range-cells = <3>;
|
||||
|
|
|
@ -1,84 +0,0 @@
|
|||
* ZTE ZX Pin Controller
|
||||
|
||||
The pin controller on ZTE ZX platforms is kinda of hybrid. It consists of
|
||||
a main controller and an auxiliary one. For example, on ZX296718 SoC, the
|
||||
main controller is TOP_PMM and the auxiliary one is AON_IOCFG. Both
|
||||
controllers work together to control pin multiplexing and configuration in
|
||||
the way illustrated as below.
|
||||
|
||||
|
||||
GMII_RXD3 ---+
|
||||
|
|
||||
DVI1_HS ---+----------------------------- GMII_RXD3 (TOP pin)
|
||||
|
|
||||
BGPIO16 ---+ ^
|
||||
| pinconf
|
||||
^ |
|
||||
| pinmux |
|
||||
| |
|
||||
|
||||
TOP_PMM (main) AON_IOCFG (aux)
|
||||
|
||||
| | |
|
||||
| pinmux | |
|
||||
| pinmux v |
|
||||
v | pinconf
|
||||
KEY_ROW2 ---+ v
|
||||
PORT1_LCD_TE ---+ |
|
||||
| AGPIO10 ---+------ KEY_ROW2 (AON pin)
|
||||
I2S0_DOUT3 ---+ |
|
||||
|-----------------------+
|
||||
PWM_OUT3 ---+
|
||||
|
|
||||
VGA_VS1 ---+
|
||||
|
||||
|
||||
For most of pins like GMII_RXD3 in the figure, the pinmux function is
|
||||
controlled by TOP_PMM block only, and this type of pins are meant by term
|
||||
'TOP pins'. For pins like KEY_ROW2, the pinmux is controlled by both
|
||||
TOP_PMM and AON_IOCFG blocks, as the available multiplexing functions for
|
||||
the pin spread in both controllers. This type of pins are called 'AON pins'.
|
||||
Though pinmux implementation is quite different, pinconf is same for both
|
||||
types of pins. Both are controlled by auxiliary controller, i.e. AON_IOCFG
|
||||
on ZX296718.
|
||||
|
||||
Required properties:
|
||||
- compatible: should be "zte,zx296718-pmm".
|
||||
- reg: the register physical address and length.
|
||||
- zte,auxiliary-controller: phandle to the auxiliary pin controller which
|
||||
implements pinmux for AON pins and pinconf for all pins.
|
||||
|
||||
The following pin configuration are supported. Please refer to
|
||||
pinctrl-bindings.txt in this directory for more details of the common
|
||||
pinctrl bindings used by client devices.
|
||||
|
||||
- bias-pull-up
|
||||
- bias-pull-down
|
||||
- drive-strength
|
||||
- input-enable
|
||||
- slew-rate
|
||||
|
||||
Examples:
|
||||
|
||||
iocfg: pin-controller@119000 {
|
||||
compatible = "zte,zx296718-iocfg";
|
||||
reg = <0x119000 0x1000>;
|
||||
};
|
||||
|
||||
pmm: pin-controller@1462000 {
|
||||
compatible = "zte,zx296718-pmm";
|
||||
reg = <0x1462000 0x1000>;
|
||||
zte,auxiliary-controller = <&iocfg>;
|
||||
};
|
||||
|
||||
&pmm {
|
||||
vga_pins: vga {
|
||||
pins = "KEY_COL1", "KEY_COL2", "KEY_ROW1", "KEY_ROW2";
|
||||
function = "VGA";
|
||||
};
|
||||
};
|
||||
|
||||
&vga {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&vga_pins>;
|
||||
};
|
|
@ -8,6 +8,7 @@ of PMIC's from Qualcomm.
|
|||
Value type: <string>
|
||||
Definition: Should contain one of:
|
||||
"qcom,pm8018-mpp",
|
||||
"qcom,pm8019-mpp",
|
||||
"qcom,pm8038-mpp",
|
||||
"qcom,pm8058-mpp",
|
||||
"qcom,pm8821-mpp",
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/pinctrl/qcom,sc8180x-pinctrl.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Technologies, Inc. SC8180X TLMM block
|
||||
|
||||
maintainers:
|
||||
- Bjorn Andersson <bjorn.andersson@linaro.org>
|
||||
|
||||
description: |
|
||||
This binding describes the Top Level Mode Multiplexer block found in the
|
||||
SC8180X platform.
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/pinctrl/qcom,tlmm-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sc8180x-tlmm
|
||||
|
||||
reg:
|
||||
maxItems: 3
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: "west"
|
||||
- const: "east"
|
||||
- const: "south"
|
||||
|
||||
interrupts: true
|
||||
interrupt-controller: true
|
||||
'#interrupt-cells': true
|
||||
gpio-controller: true
|
||||
gpio-reserved-ranges: true
|
||||
'#gpio-cells': true
|
||||
gpio-ranges: true
|
||||
wakeup-parent: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
patternProperties:
|
||||
'-state$':
|
||||
oneOf:
|
||||
- $ref: "#/$defs/qcom-sc8180x-tlmm-state"
|
||||
- patternProperties:
|
||||
".*":
|
||||
$ref: "#/$defs/qcom-sc8180x-tlmm-state"
|
||||
|
||||
'$defs':
|
||||
qcom-sc8180x-tlmm-state:
|
||||
type: object
|
||||
description:
|
||||
Pinctrl node's client devices use subnodes for desired pin configuration.
|
||||
Client device subnodes use below standard properties.
|
||||
$ref: "qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state"
|
||||
|
||||
properties:
|
||||
pins:
|
||||
description:
|
||||
List of gpio pins affected by the properties specified in this
|
||||
subnode.
|
||||
items:
|
||||
oneOf:
|
||||
- pattern: "^gpio([0-9]|[1-9][0-9]|1[0-8][0-9])$"
|
||||
- enum: [ sdc2_clk, sdc2_cmd, sdc2_data, ufs_reset ]
|
||||
minItems: 1
|
||||
maxItems: 16
|
||||
|
||||
function:
|
||||
description:
|
||||
Specify the alternative function to be configured for the specified
|
||||
pins.
|
||||
|
||||
enum: [ adsp_ext, agera_pll, aoss_cti, atest_char, atest_tsens,
|
||||
atest_tsens2, atest_usb0, atest_usb1, atest_usb2, atest_usb3,
|
||||
atest_usb4, audio_ref, btfm_slimbus, cam_mclk, cci_async,
|
||||
cci_i2c, cci_timer0, cci_timer1, cci_timer2, cci_timer3,
|
||||
cci_timer4, cci_timer5, cci_timer6, cci_timer7, cci_timer8,
|
||||
cci_timer9, cri_trng, dbg_out, ddr_bist, ddr_pxi, debug_hot,
|
||||
dp_hot, edp_hot, edp_lcd, emac_phy, emac_pps, gcc_gp1, gcc_gp2,
|
||||
gcc_gp3, gcc_gp4, gcc_gp5, gpio, gps, grfc, hs1_mi2s, hs2_mi2s,
|
||||
hs3_mi2s, jitter_bist, lpass_slimbus, m_voc, mdp_vsync,
|
||||
mdp_vsync0, mdp_vsync1, mdp_vsync2, mdp_vsync3, mdp_vsync4,
|
||||
mdp_vsync5, mss_lte, nav_pps, pa_indicator, pci_e0, pci_e1,
|
||||
pci_e2, pci_e3, phase_flag, pll_bist, pll_bypassnl, pll_reset,
|
||||
pri_mi2s, pri_mi2s_ws, prng_rosc, qdss_cti, qdss_gpio, qlink,
|
||||
qspi0, qspi0_clk, qspi0_cs, qspi1, qspi1_clk, qspi1_cs,
|
||||
qua_mi2s, qup0, qup1, qup2, qup3, qup4, qup5, qup6, qup7, qup8,
|
||||
qup9, qup10, qup11, qup12, qup13, qup14, qup15, qup16, qup17,
|
||||
qup18, qup19, qup_l4, qup_l5, qup_l6, rgmii, sd_write, sdc4,
|
||||
sdc4_clk, sdc4_cmd, sec_mi2s, sp_cmu, spkr_i2s, ter_mi2s, tgu,
|
||||
tsense_pwm1, tsense_pwm2, tsif1, tsif2, uim1, uim2, uim_batt,
|
||||
usb0_phy, usb1_phy, usb2phy_ac, vfr_1, vsense_trigger,
|
||||
wlan1_adc, wlan2_adc, wmss_reset ]
|
||||
|
||||
bias-disable: true
|
||||
bias-pull-down: true
|
||||
bias-pull-up: true
|
||||
drive-strength: true
|
||||
input-enable: true
|
||||
output-high: true
|
||||
output-low: true
|
||||
|
||||
required:
|
||||
- pins
|
||||
- function
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
pinctrl@3100000 {
|
||||
compatible = "qcom,sc8180x-tlmm";
|
||||
reg = <0x03100000 0x300000>,
|
||||
<0x03500000 0x700000>,
|
||||
<0x03d00000 0x300000>;
|
||||
reg-names = "west", "east", "south";
|
||||
interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
gpio-ranges = <&tlmm 0 0 190>;
|
||||
|
||||
gpio-wo-subnode-state {
|
||||
pins = "gpio1";
|
||||
function = "gpio";
|
||||
};
|
||||
|
||||
uart-w-subnodes-state {
|
||||
rx {
|
||||
pins = "gpio4";
|
||||
function = "qup6";
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
tx {
|
||||
pins = "gpio5";
|
||||
function = "qup6";
|
||||
bias-disable;
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
|
@ -0,0 +1,145 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/pinctrl/qcom,sm8350-pinctrl.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Technologies, Inc. SM8350 TLMM block
|
||||
|
||||
maintainers:
|
||||
- Vinod Koul <vkoul@kernel.org>
|
||||
|
||||
description: |
|
||||
This binding describes the Top Level Mode Multiplexer (TLMM) block found
|
||||
in the SM8350 platform.
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/pinctrl/qcom,tlmm-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm8350-tlmm
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts: true
|
||||
interrupt-controller: true
|
||||
'#interrupt-cells': true
|
||||
gpio-controller: true
|
||||
gpio-reserved-ranges: true
|
||||
'#gpio-cells': true
|
||||
gpio-ranges: true
|
||||
wakeup-parent: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
patternProperties:
|
||||
'-state$':
|
||||
oneOf:
|
||||
- $ref: "#/$defs/qcom-sm8350-tlmm-state"
|
||||
- patternProperties:
|
||||
".*":
|
||||
$ref: "#/$defs/qcom-sm8350-tlmm-state"
|
||||
|
||||
$defs:
|
||||
qcom-sm8350-tlmm-state:
|
||||
type: object
|
||||
description:
|
||||
Pinctrl node's client devices use subnodes for desired pin configuration.
|
||||
Client device subnodes use below standard properties.
|
||||
$ref: "qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state"
|
||||
|
||||
properties:
|
||||
pins:
|
||||
description:
|
||||
List of gpio pins affected by the properties specified in this
|
||||
subnode.
|
||||
items:
|
||||
oneOf:
|
||||
- pattern: "^gpio([0-9]|[1-9][0-9]|1[0-9][0-9]|20[0-3])$"
|
||||
- enum: [ sdc1_clk, sdc1_cmd, sdc1_data, sdc2_clk, sdc2_cmd, sdc2_data ]
|
||||
minItems: 1
|
||||
maxItems: 36
|
||||
|
||||
function:
|
||||
description:
|
||||
Specify the alternative function to be configured for the specified
|
||||
pins.
|
||||
|
||||
enum: [ atest_char, atest_usb, audio_ref, cam_mclk, cci_async,
|
||||
cci_i2c, cci_timer, cmu_rng, coex_uart1, coex_uart2, cri_trng,
|
||||
cri_trng0, cri_trng1, dbg_out, ddr_bist, ddr_pxi0, ddr_pxi1,
|
||||
ddr_pxi2, ddr_pxi3, dp_hot, dp_lcd, gcc_gp1, gcc_gp2, gcc_gp3,
|
||||
gpio, ibi_i3c, jitter_bist, lpass_slimbus, mdp_vsync, mdp_vsync0,
|
||||
mdp_vsync1, mdp_vsync2, mdp_vsync3, mi2s0_data0, mi2s0_data1,
|
||||
mi2s0_sck, mi2s0_ws, mi2s1_data0, mi2s1_data1, mi2s1_sck,
|
||||
mi2s1_ws, mi2s2_data0, mi2s2_data1, mi2s2_sck, mi2s2_ws,
|
||||
mss_grfc0, mss_grfc1, mss_grfc10, mss_grfc11, mss_grfc12,
|
||||
mss_grfc2, mss_grfc3, mss_grfc4, mss_grfc5, mss_grfc6,
|
||||
mss_grfc7, mss_grfc8, mss_grfc9, nav_gpio, pa_indicator,
|
||||
pcie0_clkreqn, pcie1_clkreqn, phase_flag, pll_bist, pll_clk,
|
||||
pri_mi2s, prng_rosc, qdss_cti, qdss_gpio, qlink0_enable,
|
||||
qlink0_request, qlink0_wmss, qlink1_enable, qlink1_request,
|
||||
qlink1_wmss, qlink2_enable, qlink2_request, qlink2_wmss, qspi0,
|
||||
qspi1, qspi2, qspi3, qspi_clk, qspi_cs, qup0, qup1, qup10,
|
||||
qup11, qup12, qup13, qup14, qup15, qup16, qup17, qup18, qup19,
|
||||
qup2, qup3, qup4, qup5, qup6, qup7, qup8, qup9, qup_l4, qup_l5,
|
||||
qup_l6, sd_write, sdc40, sdc41, sdc42, sdc43, sdc4_clk,
|
||||
sdc4_cmd, sec_mi2s, tb_trig, tgu_ch0, tgu_ch1, tgu_ch2,
|
||||
tgu_ch3, tsense_pwm1, tsense_pwm2, uim0_clk, uim0_data,
|
||||
uim0_present, uim0_reset, uim1_clk, uim1_data, uim1_present,
|
||||
uim1_reset, usb2phy_ac, usb_phy, vfr_0, vfr_1, vsense_trigger ]
|
||||
|
||||
|
||||
bias-disable: true
|
||||
bias-pull-down: true
|
||||
bias-pull-up: true
|
||||
drive-strength: true
|
||||
input-enable: true
|
||||
output-high: true
|
||||
output-low: true
|
||||
|
||||
required:
|
||||
- pins
|
||||
- function
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
pinctrl@f100000 {
|
||||
compatible = "qcom,sm8350-tlmm";
|
||||
reg = <0x0f100000 0x300000>;
|
||||
interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
gpio-ranges = <&tlmm 0 0 203>;
|
||||
|
||||
gpio-wo-subnode-state {
|
||||
pins = "gpio1";
|
||||
function = "gpio";
|
||||
};
|
||||
|
||||
uart-w-subnodes-state {
|
||||
rx {
|
||||
pins = "gpio18";
|
||||
function = "qup3";
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
tx {
|
||||
pins = "gpio19";
|
||||
function = "qup3";
|
||||
bias-disable;
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
|
@ -0,0 +1,85 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/pinctrl/qcom,tlmm-common.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Technologies, Inc. Top Level Mode Multiplexer (TLMM) definitions
|
||||
|
||||
maintainers:
|
||||
- Bjorn Andersson <bjorn.andersson@linaro.org>
|
||||
|
||||
description:
|
||||
This defines the common properties used to describe all Qualcomm Top Level
|
||||
Mode Multiplexer bindings and pinconf/pinmux states for these.
|
||||
|
||||
properties:
|
||||
interrupts:
|
||||
description:
|
||||
Specifies the TLMM summary IRQ
|
||||
maxItems: 1
|
||||
|
||||
interrupt-controller: true
|
||||
|
||||
'#interrupt-cells':
|
||||
description:
|
||||
Specifies the PIN numbers and Flags, as defined in defined in
|
||||
include/dt-bindings/interrupt-controller/irq.h
|
||||
const: 2
|
||||
|
||||
gpio-controller: true
|
||||
|
||||
'#gpio-cells':
|
||||
description:
|
||||
Specifying the pin number and flags, as defined in
|
||||
include/dt-bindings/gpio/gpio.h
|
||||
const: 2
|
||||
|
||||
gpio-ranges:
|
||||
maxItems: 1
|
||||
|
||||
wakeup-parent:
|
||||
description:
|
||||
Specifying the interrupt-controller used to wake up the system when the
|
||||
TLMM block has been powered down.
|
||||
maxItems: 1
|
||||
|
||||
gpio-reserved-ranges:
|
||||
description:
|
||||
Pins can be reserved for trusted applications and thereby unaccessible
|
||||
from the OS. This property can be used to mark the pins which resources
|
||||
should not be accessed by the OS. Please see the ../gpio/gpio.txt for more
|
||||
information.
|
||||
|
||||
required:
|
||||
- interrupts
|
||||
- interrupt-controller
|
||||
- '#interrupt-cells'
|
||||
- gpio-controller
|
||||
- '#gpio-cells'
|
||||
- gpio-ranges
|
||||
|
||||
additionalProperties: true
|
||||
|
||||
$defs:
|
||||
qcom-tlmm-state:
|
||||
allOf:
|
||||
- $ref: pincfg-node.yaml#
|
||||
- $ref: pinmux-node.yaml#
|
||||
|
||||
properties:
|
||||
drive-strength:
|
||||
enum: [2, 4, 6, 8, 10, 12, 14, 16]
|
||||
default: 2
|
||||
description:
|
||||
Selects the drive strength for the specified pins, in mA.
|
||||
|
||||
bias-pull-down: true
|
||||
bias-pull-up: true
|
||||
bias-disable: true
|
||||
input-enable: true
|
||||
output-high: true
|
||||
output-low: true
|
||||
|
||||
additionalProperties: true
|
||||
...
|
|
@ -15,39 +15,38 @@ description:
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- ralink,rt2880-pinmux
|
||||
const: ralink,rt2880-pinmux
|
||||
|
||||
pinctrl-0:
|
||||
description:
|
||||
A phandle to the node containing the subnodes containing default
|
||||
configurations. This is for pinctrl hogs.
|
||||
patternProperties:
|
||||
'-pins$':
|
||||
type: object
|
||||
patternProperties:
|
||||
'^(.*-)?pinmux$':
|
||||
type: object
|
||||
description: node for pinctrl.
|
||||
$ref: pinmux-node.yaml#
|
||||
|
||||
pinctrl-names:
|
||||
description:
|
||||
A pinctrl state named "default" can be defined.
|
||||
const: default
|
||||
properties:
|
||||
groups:
|
||||
description: Name of the pin group to use for the functions.
|
||||
enum: [i2c, spi, uart1, uart2, uart3, rgmii1, rgmii2, mdio,
|
||||
pcie, sdhci]
|
||||
function:
|
||||
description: The mux function to select
|
||||
enum: [gpio, i2c, spi, uart1, uart2, uart3, rgmii1, rgmii2,
|
||||
mdio, nand1, nand2, sdhci]
|
||||
|
||||
required:
|
||||
- groups
|
||||
- function
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
patternProperties:
|
||||
'[a-z0-9_-]+':
|
||||
if:
|
||||
type: object
|
||||
description: node for pinctrl.
|
||||
$ref: "pinmux-node.yaml"
|
||||
then:
|
||||
properties:
|
||||
groups:
|
||||
description: Name of the pin group to use for the functions.
|
||||
enum: [i2c, spi, uart1, uart2, uart3, rgmii1, rgmii2, mdio,
|
||||
pcie, sdhci]
|
||||
function:
|
||||
description: The mux function to select
|
||||
enum: [gpio, i2c, spi, uart1, uart2, uart3, rgmii1, rgmii2,
|
||||
mdio, nand1, nand2, sdhci]
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
|
@ -55,14 +54,9 @@ examples:
|
|||
- |
|
||||
pinctrl {
|
||||
compatible = "ralink,rt2880-pinmux";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&state_default>;
|
||||
|
||||
state_default: pinctrl0 {
|
||||
};
|
||||
|
||||
i2c_pins: i2c0 {
|
||||
i2c0 {
|
||||
i2c_pins: i2c0-pins {
|
||||
pinmux {
|
||||
groups = "i2c";
|
||||
function = "i2c";
|
||||
};
|
||||
|
|
|
@ -43,11 +43,12 @@ properties:
|
|||
- renesas,pfc-r8a77980 # R-Car V3H
|
||||
- renesas,pfc-r8a77990 # R-Car E3
|
||||
- renesas,pfc-r8a77995 # R-Car D3
|
||||
- renesas,pfc-r8a779a0 # R-Car V3U
|
||||
- renesas,pfc-sh73a0 # SH-Mobile AG5
|
||||
|
||||
reg:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
maxItems: 10
|
||||
|
||||
gpio-controller: true
|
||||
|
||||
|
|
|
@ -336,7 +336,7 @@ Example 3: A uart client node that supports 'default' and 'flow-control' states.
|
|||
interrupts = <0 52 0>;
|
||||
pinctrl-names = "default", "flow-control;
|
||||
pinctrl-0 = <&uart0_data>;
|
||||
pinctrl-1 = <&uart0_data &uart0_fctl>;
|
||||
pinctrl-1 = <&uart0_data>, <&uart0_fctl>;
|
||||
};
|
||||
|
||||
Example 4: Set up the default pin state for uart controller.
|
||||
|
|
45
Makefile
45
Makefile
|
@ -854,12 +854,8 @@ KBUILD_CFLAGS += $(DEBUG_CFLAGS)
|
|||
export DEBUG_CFLAGS
|
||||
|
||||
ifdef CONFIG_FUNCTION_TRACER
|
||||
ifdef CONFIG_FTRACE_MCOUNT_RECORD
|
||||
# gcc 5 supports generating the mcount tables directly
|
||||
ifeq ($(call cc-option-yn,-mrecord-mcount),y)
|
||||
CC_FLAGS_FTRACE += -mrecord-mcount
|
||||
export CC_USING_RECORD_MCOUNT := 1
|
||||
endif
|
||||
ifdef CONFIG_FTRACE_MCOUNT_USE_CC
|
||||
CC_FLAGS_FTRACE += -mrecord-mcount
|
||||
ifdef CONFIG_HAVE_NOP_MCOUNT
|
||||
ifeq ($(call cc-option-yn, -mnop-mcount),y)
|
||||
CC_FLAGS_FTRACE += -mnop-mcount
|
||||
|
@ -867,6 +863,12 @@ ifdef CONFIG_FTRACE_MCOUNT_RECORD
|
|||
endif
|
||||
endif
|
||||
endif
|
||||
ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT
|
||||
ifdef CONFIG_HAVE_C_RECORDMCOUNT
|
||||
BUILD_C_RECORDMCOUNT := y
|
||||
export BUILD_C_RECORDMCOUNT
|
||||
endif
|
||||
endif
|
||||
ifdef CONFIG_HAVE_FENTRY
|
||||
ifeq ($(call cc-option-yn, -mfentry),y)
|
||||
CC_FLAGS_FTRACE += -mfentry
|
||||
|
@ -876,12 +878,6 @@ endif
|
|||
export CC_FLAGS_FTRACE
|
||||
KBUILD_CFLAGS += $(CC_FLAGS_FTRACE) $(CC_FLAGS_USING)
|
||||
KBUILD_AFLAGS += $(CC_FLAGS_USING)
|
||||
ifdef CONFIG_DYNAMIC_FTRACE
|
||||
ifdef CONFIG_HAVE_C_RECORDMCOUNT
|
||||
BUILD_C_RECORDMCOUNT := y
|
||||
export BUILD_C_RECORDMCOUNT
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# We trigger additional mismatches with less inlining
|
||||
|
@ -900,6 +896,24 @@ KBUILD_CFLAGS += $(CC_FLAGS_SCS)
|
|||
export CC_FLAGS_SCS
|
||||
endif
|
||||
|
||||
ifdef CONFIG_LTO_CLANG
|
||||
ifdef CONFIG_LTO_CLANG_THIN
|
||||
CC_FLAGS_LTO := -flto=thin -fsplit-lto-unit
|
||||
KBUILD_LDFLAGS += --thinlto-cache-dir=$(extmod-prefix).thinlto-cache
|
||||
else
|
||||
CC_FLAGS_LTO := -flto
|
||||
endif
|
||||
CC_FLAGS_LTO += -fvisibility=hidden
|
||||
|
||||
# Limit inlining across translation units to reduce binary size
|
||||
KBUILD_LDFLAGS += -mllvm -import-instr-limit=5
|
||||
endif
|
||||
|
||||
ifdef CONFIG_LTO
|
||||
KBUILD_CFLAGS += $(CC_FLAGS_LTO)
|
||||
export CC_FLAGS_LTO
|
||||
endif
|
||||
|
||||
ifdef CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_32B
|
||||
KBUILD_CFLAGS += -falign-functions=32
|
||||
endif
|
||||
|
@ -1509,7 +1523,7 @@ MRPROPER_FILES += include/config include/generated \
|
|||
*.spec
|
||||
|
||||
# Directories & files removed with 'make distclean'
|
||||
DISTCLEAN_FILES += tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS
|
||||
DISTCLEAN_FILES += tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS .thinlto-cache
|
||||
|
||||
# clean - Delete most, but leave enough to build external modules
|
||||
#
|
||||
|
@ -1755,7 +1769,7 @@ PHONY += compile_commands.json
|
|||
|
||||
clean-dirs := $(KBUILD_EXTMOD)
|
||||
clean: rm-files := $(KBUILD_EXTMOD)/Module.symvers $(KBUILD_EXTMOD)/modules.nsdeps \
|
||||
$(KBUILD_EXTMOD)/compile_commands.json
|
||||
$(KBUILD_EXTMOD)/compile_commands.json $(KBUILD_EXTMOD)/.thinlto-cache
|
||||
|
||||
PHONY += help
|
||||
help:
|
||||
|
@ -1854,7 +1868,8 @@ clean: $(clean-dirs)
|
|||
-o -name '.tmp_*.o.*' \
|
||||
-o -name '*.c.[012]*.*' \
|
||||
-o -name '*.ll' \
|
||||
-o -name '*.gcno' \) -type f -print | xargs rm -f
|
||||
-o -name '*.gcno' \
|
||||
-o -name '*.*.symversions' \) -type f -print | xargs rm -f
|
||||
|
||||
# Generate tags for editors
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
90
arch/Kconfig
90
arch/Kconfig
|
@ -603,6 +603,96 @@ config SHADOW_CALL_STACK
|
|||
reading and writing arbitrary memory may be able to locate them
|
||||
and hijack control flow by modifying the stacks.
|
||||
|
||||
config LTO
|
||||
bool
|
||||
help
|
||||
Selected if the kernel will be built using the compiler's LTO feature.
|
||||
|
||||
config LTO_CLANG
|
||||
bool
|
||||
select LTO
|
||||
help
|
||||
Selected if the kernel will be built using Clang's LTO feature.
|
||||
|
||||
config ARCH_SUPPORTS_LTO_CLANG
|
||||
bool
|
||||
help
|
||||
An architecture should select this option if it supports:
|
||||
- compiling with Clang,
|
||||
- compiling inline assembly with Clang's integrated assembler,
|
||||
- and linking with LLD.
|
||||
|
||||
config ARCH_SUPPORTS_LTO_CLANG_THIN
|
||||
bool
|
||||
help
|
||||
An architecture should select this option if it can support Clang's
|
||||
ThinLTO mode.
|
||||
|
||||
config HAS_LTO_CLANG
|
||||
def_bool y
|
||||
# Clang >= 11: https://github.com/ClangBuiltLinux/linux/issues/510
|
||||
depends on CC_IS_CLANG && CLANG_VERSION >= 110000 && LD_IS_LLD
|
||||
depends on $(success,test $(LLVM) -eq 1)
|
||||
depends on $(success,test $(LLVM_IAS) -eq 1)
|
||||
depends on $(success,$(NM) --help | head -n 1 | grep -qi llvm)
|
||||
depends on $(success,$(AR) --help | head -n 1 | grep -qi llvm)
|
||||
depends on ARCH_SUPPORTS_LTO_CLANG
|
||||
depends on !FTRACE_MCOUNT_USE_RECORDMCOUNT
|
||||
depends on !KASAN
|
||||
depends on !GCOV_KERNEL
|
||||
help
|
||||
The compiler and Kconfig options support building with Clang's
|
||||
LTO.
|
||||
|
||||
choice
|
||||
prompt "Link Time Optimization (LTO)"
|
||||
default LTO_NONE
|
||||
help
|
||||
This option enables Link Time Optimization (LTO), which allows the
|
||||
compiler to optimize binaries globally.
|
||||
|
||||
If unsure, select LTO_NONE. Note that LTO is very resource-intensive
|
||||
so it's disabled by default.
|
||||
|
||||
config LTO_NONE
|
||||
bool "None"
|
||||
help
|
||||
Build the kernel normally, without Link Time Optimization (LTO).
|
||||
|
||||
config LTO_CLANG_FULL
|
||||
bool "Clang Full LTO (EXPERIMENTAL)"
|
||||
depends on HAS_LTO_CLANG
|
||||
depends on !COMPILE_TEST
|
||||
select LTO_CLANG
|
||||
help
|
||||
This option enables Clang's full Link Time Optimization (LTO), which
|
||||
allows the compiler to optimize the kernel globally. If you enable
|
||||
this option, the compiler generates LLVM bitcode instead of ELF
|
||||
object files, and the actual compilation from bitcode happens at
|
||||
the LTO link step, which may take several minutes depending on the
|
||||
kernel configuration. More information can be found from LLVM's
|
||||
documentation:
|
||||
|
||||
https://llvm.org/docs/LinkTimeOptimization.html
|
||||
|
||||
During link time, this option can use a large amount of RAM, and
|
||||
may take much longer than the ThinLTO option.
|
||||
|
||||
config LTO_CLANG_THIN
|
||||
bool "Clang ThinLTO (EXPERIMENTAL)"
|
||||
depends on HAS_LTO_CLANG && ARCH_SUPPORTS_LTO_CLANG_THIN
|
||||
select LTO_CLANG
|
||||
help
|
||||
This option enables Clang's ThinLTO, which allows for parallel
|
||||
optimization and faster incremental compiles compared to the
|
||||
CONFIG_LTO_CLANG_FULL option. More information can be found
|
||||
from Clang's documentation:
|
||||
|
||||
https://clang.llvm.org/docs/ThinLTO.html
|
||||
|
||||
If unsure, say Y.
|
||||
endchoice
|
||||
|
||||
config HAVE_ARCH_WITHIN_STACK_FRAMES
|
||||
bool
|
||||
help
|
||||
|
|
|
@ -176,7 +176,6 @@ CONFIG_BOOT_PRINTK_DELAY=y
|
|||
CONFIG_DYNAMIC_DEBUG=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
# CONFIG_ENABLE_MUST_CHECK is not set
|
||||
CONFIG_UNUSED_SYMBOLS=y
|
||||
CONFIG_DEBUG_MEMORY_INIT=y
|
||||
CONFIG_LOCKUP_DETECTOR=y
|
||||
CONFIG_SCHED_TRACER=y
|
||||
|
|
|
@ -164,7 +164,6 @@ CONFIG_FONTS=y
|
|||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_FRAME_WARN=2048
|
||||
CONFIG_UNUSED_SYMBOLS=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
CONFIG_SOFTLOCKUP_DETECTOR=y
|
||||
|
|
|
@ -73,6 +73,8 @@ config ARM64
|
|||
select ARCH_SUPPORTS_DEBUG_PAGEALLOC
|
||||
select ARCH_SUPPORTS_MEMORY_FAILURE
|
||||
select ARCH_SUPPORTS_SHADOW_CALL_STACK if CC_HAVE_SHADOW_CALL_STACK
|
||||
select ARCH_SUPPORTS_LTO_CLANG if CPU_LITTLE_ENDIAN
|
||||
select ARCH_SUPPORTS_LTO_CLANG_THIN
|
||||
select ARCH_SUPPORTS_ATOMIC_RMW
|
||||
select ARCH_SUPPORTS_INT128 if CC_HAS_INT128 && (GCC_VERSION >= 50000 || CC_IS_CLANG)
|
||||
select ARCH_SUPPORTS_NUMA_BALANCING
|
||||
|
@ -162,6 +164,8 @@ config ARM64
|
|||
select HAVE_DYNAMIC_FTRACE
|
||||
select HAVE_DYNAMIC_FTRACE_WITH_REGS \
|
||||
if $(cc-option,-fpatchable-function-entry=2)
|
||||
select FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY \
|
||||
if DYNAMIC_FTRACE_WITH_REGS
|
||||
select HAVE_EFFICIENT_UNALIGNED_ACCESS
|
||||
select HAVE_FAST_GUP
|
||||
select HAVE_FTRACE_MCOUNT_RECORD
|
||||
|
|
|
@ -29,7 +29,8 @@ ldflags-y := -shared -nostdlib -soname=linux-vdso.so.1 --hash-style=sysv \
|
|||
ccflags-y := -fno-common -fno-builtin -fno-stack-protector -ffixed-x18
|
||||
ccflags-y += -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO
|
||||
|
||||
CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) $(GCC_PLUGINS_CFLAGS)
|
||||
CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) $(GCC_PLUGINS_CFLAGS) \
|
||||
$(CC_FLAGS_LTO)
|
||||
KASAN_SANITIZE := n
|
||||
UBSAN_SANITIZE := n
|
||||
OBJECT_FILES_NON_STANDARD := y
|
||||
|
|
|
@ -38,7 +38,6 @@ config MICROBLAZE
|
|||
select OF_EARLY_FLATTREE
|
||||
select PCI_DOMAINS_GENERIC if PCI
|
||||
select PCI_SYSCALL if PCI
|
||||
select TRACING_SUPPORT
|
||||
select VIRT_TO_BUS
|
||||
select CPU_NO_EFFICIENT_FFS
|
||||
select MMU_GATHER_NO_RANGE
|
||||
|
|
|
@ -24,9 +24,6 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
|
|||
Elf32_Sym *sym;
|
||||
unsigned long int *location;
|
||||
unsigned long int value;
|
||||
#if __GNUC__ < 4
|
||||
unsigned long int old_value;
|
||||
#endif
|
||||
|
||||
pr_debug("Applying add relocation section %u to %u\n",
|
||||
relsec, sechdrs[relsec].sh_info);
|
||||
|
@ -49,40 +46,17 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
|
|||
*/
|
||||
|
||||
case R_MICROBLAZE_32:
|
||||
#if __GNUC__ < 4
|
||||
old_value = *location;
|
||||
*location = value + old_value;
|
||||
|
||||
pr_debug("R_MICROBLAZE_32 (%08lx->%08lx)\n",
|
||||
old_value, value);
|
||||
#else
|
||||
*location = value;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case R_MICROBLAZE_64:
|
||||
#if __GNUC__ < 4
|
||||
/* Split relocs only required/used pre gcc4.1.1 */
|
||||
old_value = ((location[0] & 0x0000FFFF) << 16) |
|
||||
(location[1] & 0x0000FFFF);
|
||||
value += old_value;
|
||||
#endif
|
||||
location[0] = (location[0] & 0xFFFF0000) |
|
||||
(value >> 16);
|
||||
location[1] = (location[1] & 0xFFFF0000) |
|
||||
(value & 0xFFFF);
|
||||
#if __GNUC__ < 4
|
||||
pr_debug("R_MICROBLAZE_64 (%08lx->%08lx)\n",
|
||||
old_value, value);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case R_MICROBLAZE_64_PCREL:
|
||||
#if __GNUC__ < 4
|
||||
old_value = (location[0] & 0xFFFF) << 16 |
|
||||
(location[1] & 0xFFFF);
|
||||
value -= old_value;
|
||||
#endif
|
||||
value -= (unsigned long int)(location) + 4;
|
||||
location[0] = (location[0] & 0xFFFF0000) |
|
||||
(value >> 16);
|
||||
|
|
|
@ -45,7 +45,7 @@ SECTIONS {
|
|||
_etext = . ;
|
||||
}
|
||||
|
||||
. = ALIGN (4) ;
|
||||
. = ALIGN (8) ;
|
||||
__fdt_blob : AT(ADDR(__fdt_blob) - LOAD_OFFSET) {
|
||||
_fdt_start = . ; /* place for fdt blob */
|
||||
*(__fdt_blob) ; /* Any link-placed DTB */
|
||||
|
|
|
@ -549,7 +549,6 @@ CONFIG_PRINTK_TIME=y
|
|||
CONFIG_DEBUG_INFO=y
|
||||
# CONFIG_ENABLE_MUST_CHECK is not set
|
||||
CONFIG_FRAME_WARN=1024
|
||||
CONFIG_UNUSED_SYMBOLS=y
|
||||
CONFIG_DEBUG_MEMORY_INIT=y
|
||||
CONFIG_DETECT_HUNG_TASK=y
|
||||
CONFIG_SCHEDSTATS=y
|
||||
|
|
|
@ -500,7 +500,6 @@ CONFIG_CRC7=m
|
|||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
# CONFIG_ENABLE_MUST_CHECK is not set
|
||||
CONFIG_UNUSED_SYMBOLS=y
|
||||
CONFIG_DEBUG_MEMORY_INIT=y
|
||||
CONFIG_DETECT_HUNG_TASK=y
|
||||
CONFIG_SCHEDSTATS=y
|
||||
|
|
|
@ -22,7 +22,6 @@ CONFIG_PCI_LBA=y
|
|||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_MODULE_FORCE_UNLOAD=y
|
||||
CONFIG_UNUSED_SYMBOLS=y
|
||||
# CONFIG_BLK_DEV_BSG is not set
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
CONFIG_BINFMT_MISC=m
|
||||
|
|
|
@ -31,7 +31,6 @@ CONFIG_MODULE_FORCE_LOAD=y
|
|||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_MODULE_FORCE_UNLOAD=y
|
||||
CONFIG_MODVERSIONS=y
|
||||
CONFIG_UNUSED_SYMBOLS=y
|
||||
CONFIG_BLK_DEV_INTEGRITY=y
|
||||
CONFIG_BINFMT_MISC=m
|
||||
# CONFIG_COMPACTION is not set
|
||||
|
|
|
@ -196,7 +196,6 @@ config PPC
|
|||
select HAVE_STACKPROTECTOR if PPC64 && $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r13)
|
||||
select HAVE_STACKPROTECTOR if PPC32 && $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r2)
|
||||
select HAVE_CONTEXT_TRACKING if PPC64
|
||||
select HAVE_TIF_NOHZ if PPC64
|
||||
select HAVE_DEBUG_KMEMLEAK
|
||||
select HAVE_DEBUG_STACKOVERFLOW
|
||||
select HAVE_DYNAMIC_FTRACE
|
||||
|
@ -503,18 +502,14 @@ config HOTPLUG_CPU
|
|||
Say N if you are unsure.
|
||||
|
||||
config PPC_QUEUED_SPINLOCKS
|
||||
bool "Queued spinlocks"
|
||||
bool "Queued spinlocks" if EXPERT
|
||||
depends on SMP
|
||||
default PPC_BOOK3S_64
|
||||
help
|
||||
Say Y here to use queued spinlocks which give better scalability and
|
||||
fairness on large SMP and NUMA systems without harming single threaded
|
||||
performance.
|
||||
|
||||
This option is currently experimental, the code is more complex and
|
||||
less tested so it defaults to "N" for the moment.
|
||||
|
||||
If unsure, say "N".
|
||||
|
||||
config ARCH_CPU_PROBE_RELEASE
|
||||
def_bool y
|
||||
depends on HOTPLUG_CPU
|
||||
|
@ -718,18 +713,6 @@ config ARCH_MEMORY_PROBE
|
|||
def_bool y
|
||||
depends on MEMORY_HOTPLUG
|
||||
|
||||
config STDBINUTILS
|
||||
bool "Using standard binutils settings"
|
||||
depends on 44x
|
||||
default y
|
||||
help
|
||||
Turning this option off allows you to select 256KB PAGE_SIZE on 44x.
|
||||
Note, that kernel will be able to run only those applications,
|
||||
which had been compiled using binutils later than 2.17.50.0.3 with
|
||||
'-zmax-page-size' set to 256K (the default is 64K). Or, if using
|
||||
the older binutils, you can patch them with a trivial patch, which
|
||||
changes the ELF_MAXPAGESIZE definition from 0x10000 to 0x40000.
|
||||
|
||||
choice
|
||||
prompt "Page size"
|
||||
default PPC_4K_PAGES
|
||||
|
@ -769,17 +752,15 @@ config PPC_64K_PAGES
|
|||
select HAVE_ARCH_SOFT_DIRTY if PPC_BOOK3S_64
|
||||
|
||||
config PPC_256K_PAGES
|
||||
bool "256k page size"
|
||||
depends on 44x && !STDBINUTILS
|
||||
bool "256k page size (Requires non-standard binutils settings)"
|
||||
depends on 44x && !PPC_47x
|
||||
help
|
||||
Make the page size 256k.
|
||||
|
||||
As the ELF standard only requires alignment to support page
|
||||
sizes up to 64k, you will need to compile all of your user
|
||||
space applications with a non-standard binutils settings
|
||||
(see the STDBINUTILS description for details).
|
||||
|
||||
Say N unless you know what you are doing.
|
||||
The kernel will only be able to run applications that have been
|
||||
compiled with '-zmax-page-size' set to 256K (the default is 64K) using
|
||||
binutils later than 2.17.50.0.3, or by patching the ELF_MAXPAGESIZE
|
||||
definition from 0x10000 to 0x40000 in older versions.
|
||||
|
||||
endchoice
|
||||
|
||||
|
|
|
@ -88,6 +88,7 @@ config PPC_IRQ_SOFT_MASK_DEBUG
|
|||
config XMON
|
||||
bool "Include xmon kernel debugger"
|
||||
depends on DEBUG_KERNEL
|
||||
select CONSOLE_POLL if SERIAL_CPM_CONSOLE
|
||||
help
|
||||
Include in-kernel hooks for the xmon kernel monitor/debugger.
|
||||
Unless you are intending to debug the kernel, say N here.
|
||||
|
|
|
@ -20,6 +20,7 @@ CONFIG_IRQ_ALL_CPUS=y
|
|||
# CONFIG_COMPACTION is not set
|
||||
# CONFIG_SUSPEND is not set
|
||||
CONFIG_NET=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_INET=y
|
||||
|
@ -40,7 +41,9 @@ CONFIG_BLK_DEV_RAM_SIZE=35000
|
|||
# CONFIG_SCSI_PROC_FS is not set
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
# CONFIG_SCSI_LOWLEVEL is not set
|
||||
CONFIG_ATA=y
|
||||
# CONFIG_SATA_PMP is not set
|
||||
CONFIG_SATA_AHCI_PLATFORM=y
|
||||
# CONFIG_ATA_SFF is not set
|
||||
# CONFIG_NET_VENDOR_3COM is not set
|
||||
# CONFIG_NET_VENDOR_ADAPTEC is not set
|
||||
|
@ -97,6 +100,8 @@ CONFIG_USB_OHCI_HCD=y
|
|||
# CONFIG_USB_OHCI_HCD_PCI is not set
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_PLTFM=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_M41T80=y
|
||||
CONFIG_EXT2_FS=y
|
||||
|
|
|
@ -1071,7 +1071,6 @@ CONFIG_NLS_ISO8859_15=m
|
|||
CONFIG_NLS_KOI8_R=m
|
||||
CONFIG_NLS_KOI8_U=m
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_UNUSED_SYMBOLS=y
|
||||
CONFIG_HEADERS_INSTALL=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
|
|
|
@ -56,35 +56,6 @@ int exit_vmx_usercopy(void);
|
|||
int enter_vmx_ops(void);
|
||||
void *exit_vmx_ops(void *dest);
|
||||
|
||||
/* Traps */
|
||||
long machine_check_early(struct pt_regs *regs);
|
||||
long hmi_exception_realmode(struct pt_regs *regs);
|
||||
void SMIException(struct pt_regs *regs);
|
||||
void handle_hmi_exception(struct pt_regs *regs);
|
||||
void instruction_breakpoint_exception(struct pt_regs *regs);
|
||||
void RunModeException(struct pt_regs *regs);
|
||||
void single_step_exception(struct pt_regs *regs);
|
||||
void program_check_exception(struct pt_regs *regs);
|
||||
void alignment_exception(struct pt_regs *regs);
|
||||
void StackOverflow(struct pt_regs *regs);
|
||||
void stack_overflow_exception(struct pt_regs *regs);
|
||||
void kernel_fp_unavailable_exception(struct pt_regs *regs);
|
||||
void altivec_unavailable_exception(struct pt_regs *regs);
|
||||
void vsx_unavailable_exception(struct pt_regs *regs);
|
||||
void fp_unavailable_tm(struct pt_regs *regs);
|
||||
void altivec_unavailable_tm(struct pt_regs *regs);
|
||||
void vsx_unavailable_tm(struct pt_regs *regs);
|
||||
void facility_unavailable_exception(struct pt_regs *regs);
|
||||
void TAUException(struct pt_regs *regs);
|
||||
void altivec_assist_exception(struct pt_regs *regs);
|
||||
void unrecoverable_exception(struct pt_regs *regs);
|
||||
void kernel_bad_stack(struct pt_regs *regs);
|
||||
void system_reset_exception(struct pt_regs *regs);
|
||||
void machine_check_exception(struct pt_regs *regs);
|
||||
void emulation_assist_interrupt(struct pt_regs *regs);
|
||||
long do_slb_fault(struct pt_regs *regs, unsigned long ea);
|
||||
void do_bad_slb_fault(struct pt_regs *regs, unsigned long ea, long err);
|
||||
|
||||
/* signals, syscalls and interrupts */
|
||||
long sys_swapcontext(struct ucontext __user *old_ctx,
|
||||
struct ucontext __user *new_ctx,
|
||||
|
|
|
@ -95,12 +95,12 @@ static inline void kuap_update_sr(u32 sr, u32 addr, u32 end)
|
|||
addr &= 0xf0000000; /* align addr to start of segment */
|
||||
barrier(); /* make sure thread.kuap is updated before playing with SRs */
|
||||
while (addr < end) {
|
||||
mtsrin(sr, addr);
|
||||
mtsr(sr, addr);
|
||||
sr += 0x111; /* next VSID */
|
||||
sr &= 0xf0ffffff; /* clear VSID overflow */
|
||||
addr += 0x10000000; /* address of next segment */
|
||||
}
|
||||
isync(); /* Context sync required after mtsrin() */
|
||||
isync(); /* Context sync required after mtsr() */
|
||||
}
|
||||
|
||||
static __always_inline void allow_user_access(void __user *to, const void __user *from,
|
||||
|
@ -122,7 +122,7 @@ static __always_inline void allow_user_access(void __user *to, const void __user
|
|||
end = min(addr + size, TASK_SIZE);
|
||||
|
||||
current->thread.kuap = (addr & 0xf0000000) | ((((end - 1) >> 28) + 1) & 0xf);
|
||||
kuap_update_sr(mfsrin(addr) & ~SR_KS, addr, end); /* Clear Ks */
|
||||
kuap_update_sr(mfsr(addr) & ~SR_KS, addr, end); /* Clear Ks */
|
||||
}
|
||||
|
||||
static __always_inline void prevent_user_access(void __user *to, const void __user *from,
|
||||
|
@ -151,7 +151,7 @@ static __always_inline void prevent_user_access(void __user *to, const void __us
|
|||
}
|
||||
|
||||
current->thread.kuap = 0;
|
||||
kuap_update_sr(mfsrin(addr) | SR_KS, addr, end); /* set Ks */
|
||||
kuap_update_sr(mfsr(addr) | SR_KS, addr, end); /* set Ks */
|
||||
}
|
||||
|
||||
static inline unsigned long prevent_user_access_return(void)
|
||||
|
|
|
@ -94,7 +94,7 @@ typedef struct {
|
|||
} mm_context_t;
|
||||
|
||||
void update_bats(void);
|
||||
static inline void cleanup_cpu_mmu_context(void) { };
|
||||
static inline void cleanup_cpu_mmu_context(void) { }
|
||||
|
||||
/* patch sites */
|
||||
extern s32 patch__hash_page_A0, patch__hash_page_A1, patch__hash_page_A2;
|
||||
|
|
|
@ -339,7 +339,7 @@ static inline unsigned long get_kuap(void)
|
|||
* This has no effect in terms of actually blocking things on hash,
|
||||
* so it doesn't break anything.
|
||||
*/
|
||||
if (!early_mmu_has_feature(MMU_FTR_BOOK3S_KUAP))
|
||||
if (!mmu_has_feature(MMU_FTR_BOOK3S_KUAP))
|
||||
return AMR_KUAP_BLOCKED;
|
||||
|
||||
return mfspr(SPRN_AMR);
|
||||
|
@ -347,7 +347,7 @@ static inline unsigned long get_kuap(void)
|
|||
|
||||
static inline void set_kuap(unsigned long value)
|
||||
{
|
||||
if (!early_mmu_has_feature(MMU_FTR_BOOK3S_KUAP))
|
||||
if (!mmu_has_feature(MMU_FTR_BOOK3S_KUAP))
|
||||
return;
|
||||
|
||||
/*
|
||||
|
|
|
@ -454,6 +454,8 @@ static inline unsigned long hpt_hash(unsigned long vpn,
|
|||
#define HPTE_NOHPTE_UPDATE 0x2
|
||||
#define HPTE_USE_KERNEL_KEY 0x4
|
||||
|
||||
long hpte_insert_repeating(unsigned long hash, unsigned long vpn, unsigned long pa,
|
||||
unsigned long rlags, unsigned long vflags, int psize, int ssize);
|
||||
extern int __hash_page_4K(unsigned long ea, unsigned long access,
|
||||
unsigned long vsid, pte_t *ptep, unsigned long trap,
|
||||
unsigned long flags, int ssize, int subpage_prot);
|
||||
|
@ -467,6 +469,8 @@ extern int hash_page_mm(struct mm_struct *mm, unsigned long ea,
|
|||
unsigned long flags);
|
||||
extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap,
|
||||
unsigned long dsisr);
|
||||
void low_hash_fault(struct pt_regs *regs, unsigned long address, int rc);
|
||||
int __hash_page(unsigned long trap, unsigned long ea, unsigned long dsisr, unsigned long msr);
|
||||
int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
|
||||
pte_t *ptep, unsigned long trap, unsigned long flags,
|
||||
int ssize, unsigned int shift, unsigned int mmu_psize);
|
||||
|
@ -521,6 +525,7 @@ void slb_dump_contents(struct slb_entry *slb_ptr);
|
|||
|
||||
extern void slb_vmalloc_update(void);
|
||||
extern void slb_set_size(u16 size);
|
||||
void preload_new_slb_context(unsigned long start, unsigned long sp);
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
/*
|
||||
|
|
|
@ -239,7 +239,7 @@ static inline void setup_initial_memory_limit(phys_addr_t first_memblock_base,
|
|||
#ifdef CONFIG_PPC_PSERIES
|
||||
extern void radix_init_pseries(void);
|
||||
#else
|
||||
static inline void radix_init_pseries(void) { };
|
||||
static inline void radix_init_pseries(void) { }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
|
|
|
@ -388,11 +388,28 @@ static inline int __ptep_test_and_clear_young(struct mm_struct *mm,
|
|||
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
|
||||
#define ptep_test_and_clear_young(__vma, __addr, __ptep) \
|
||||
({ \
|
||||
int __r; \
|
||||
__r = __ptep_test_and_clear_young((__vma)->vm_mm, __addr, __ptep); \
|
||||
__r; \
|
||||
__ptep_test_and_clear_young((__vma)->vm_mm, __addr, __ptep); \
|
||||
})
|
||||
|
||||
/*
|
||||
* On Book3S CPUs, clearing the accessed bit without a TLB flush
|
||||
* doesn't cause data corruption. [ It could cause incorrect
|
||||
* page aging and the (mistaken) reclaim of hot pages, but the
|
||||
* chance of that should be relatively low. ]
|
||||
*
|
||||
* So as a performance optimization don't flush the TLB when
|
||||
* clearing the accessed bit, it will eventually be flushed by
|
||||
* a context switch or a VM operation anyway. [ In the rare
|
||||
* event of it not getting flushed for a long time the delay
|
||||
* shouldn't really matter because there's no real memory
|
||||
* pressure for swapout to react to. ]
|
||||
*/
|
||||
#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
|
||||
#define ptep_clear_flush_young ptep_test_and_clear_young
|
||||
|
||||
#define __HAVE_ARCH_PMDP_CLEAR_YOUNG_FLUSH
|
||||
#define pmdp_clear_flush_young pmdp_test_and_clear_young
|
||||
|
||||
static inline int __pte_write(pte_t pte)
|
||||
{
|
||||
return !!(pte_raw(pte) & cpu_to_be64(_PAGE_WRITE));
|
||||
|
|
|
@ -35,7 +35,7 @@ extern void radix__flush_pwc_lpid(unsigned int lpid);
|
|||
extern void radix__flush_all_lpid(unsigned int lpid);
|
||||
extern void radix__flush_all_lpid_guest(unsigned int lpid);
|
||||
#else
|
||||
static inline void radix__tlbiel_all(unsigned int action) { WARN_ON(1); };
|
||||
static inline void radix__tlbiel_all(unsigned int action) { WARN_ON(1); }
|
||||
static inline void radix__flush_tlb_lpid_page(unsigned int lpid,
|
||||
unsigned long addr,
|
||||
unsigned long page_size)
|
||||
|
|
|
@ -31,7 +31,7 @@ static inline void tlbiel_all(void)
|
|||
hash__tlbiel_all(TLB_INVAL_SCOPE_GLOBAL);
|
||||
}
|
||||
#else
|
||||
static inline void tlbiel_all(void) { BUG(); };
|
||||
static inline void tlbiel_all(void) { BUG(); }
|
||||
#endif
|
||||
|
||||
static inline void tlbiel_all_lpid(bool radix)
|
||||
|
|
|
@ -111,12 +111,15 @@
|
|||
#ifndef __ASSEMBLY__
|
||||
|
||||
struct pt_regs;
|
||||
extern int do_page_fault(struct pt_regs *, unsigned long, unsigned long);
|
||||
extern void bad_page_fault(struct pt_regs *, unsigned long, int);
|
||||
void __bad_page_fault(struct pt_regs *regs, unsigned long address, int sig);
|
||||
long do_page_fault(struct pt_regs *);
|
||||
long hash__do_page_fault(struct pt_regs *);
|
||||
void bad_page_fault(struct pt_regs *, int);
|
||||
void __bad_page_fault(struct pt_regs *regs, int sig);
|
||||
void do_bad_page_fault_segv(struct pt_regs *regs);
|
||||
extern void _exception(int, struct pt_regs *, int, unsigned long);
|
||||
extern void _exception_pkey(struct pt_regs *, unsigned long, int);
|
||||
extern void die(const char *, struct pt_regs *, long);
|
||||
void die_mce(const char *str, struct pt_regs *regs, long err);
|
||||
extern bool die_will_crash(void);
|
||||
extern void panic_flush_kmsg_start(void);
|
||||
extern void panic_flush_kmsg_end(void);
|
||||
|
|
|
@ -8,6 +8,12 @@
|
|||
#include <asm/cputable.h>
|
||||
#include <asm/cpu_has_feature.h>
|
||||
|
||||
/*
|
||||
* This flag is used to indicate that the page pointed to by a pte is clean
|
||||
* and does not require cleaning before returning it to the user.
|
||||
*/
|
||||
#define PG_dcache_clean PG_arch_1
|
||||
|
||||
#ifdef CONFIG_PPC_BOOK3S_64
|
||||
/*
|
||||
* Book3s has no ptesync after setting a pte, so without this ptesync it's
|
||||
|
|
|
@ -87,6 +87,17 @@ static notrace inline void account_cpu_user_exit(void)
|
|||
acct->starttime_user = tb;
|
||||
}
|
||||
|
||||
static notrace inline void account_stolen_time(void)
|
||||
{
|
||||
#ifdef CONFIG_PPC_SPLPAR
|
||||
if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
|
||||
struct lppaca *lp = local_paca->lppaca_ptr;
|
||||
|
||||
if (unlikely(local_paca->dtl_ridx != be64_to_cpu(lp->dtl_idx)))
|
||||
accumulate_stolen_time();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#else /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
|
||||
|
@ -96,5 +107,8 @@ static inline void account_cpu_user_entry(void)
|
|||
static inline void account_cpu_user_exit(void)
|
||||
{
|
||||
}
|
||||
static notrace inline void account_stolen_time(void)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
|
||||
#endif /* __POWERPC_CPUTIME_H */
|
||||
|
|
|
@ -50,10 +50,6 @@ bool ppc_breakpoint_available(void);
|
|||
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
|
||||
extern void do_send_trap(struct pt_regs *regs, unsigned long address,
|
||||
unsigned long error_code, int brkpt);
|
||||
#else
|
||||
|
||||
extern void do_break(struct pt_regs *regs, unsigned long address,
|
||||
unsigned long error_code);
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_POWERPC_DEBUG_H */
|
||||
|
|
|
@ -137,7 +137,7 @@ extern unsigned int __start___fw_ftr_fixup, __stop___fw_ftr_fixup;
|
|||
#ifdef CONFIG_PPC_PSERIES
|
||||
void pseries_probe_fw_features(void);
|
||||
#else
|
||||
static inline void pseries_probe_fw_features(void) { };
|
||||
static inline void pseries_probe_fw_features(void) { }
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
|
|
@ -17,8 +17,6 @@ extern bool hugetlb_disabled;
|
|||
|
||||
void hugetlbpage_init_default(void);
|
||||
|
||||
void flush_dcache_icache_hugepage(struct page *page);
|
||||
|
||||
int slice_is_hugepage_only_range(struct mm_struct *mm, unsigned long addr,
|
||||
unsigned long len);
|
||||
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
#define PACA_IRQ_MUST_HARD_MASK (PACA_IRQ_EE)
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_PPC64 */
|
||||
|
||||
/*
|
||||
* flags for paca->irq_soft_mask
|
||||
*/
|
||||
|
@ -46,18 +48,56 @@
|
|||
#define IRQS_PMI_DISABLED 2
|
||||
#define IRQS_ALL_DISABLED (IRQS_DISABLED | IRQS_PMI_DISABLED)
|
||||
|
||||
#endif /* CONFIG_PPC64 */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
extern void replay_system_reset(void);
|
||||
extern void replay_soft_interrupts(void);
|
||||
static inline void __hard_irq_enable(void)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_BOOKE) || IS_ENABLED(CONFIG_40x))
|
||||
wrtee(MSR_EE);
|
||||
else if (IS_ENABLED(CONFIG_PPC_8xx))
|
||||
wrtspr(SPRN_EIE);
|
||||
else if (IS_ENABLED(CONFIG_PPC_BOOK3S_64))
|
||||
__mtmsrd(MSR_EE | MSR_RI, 1);
|
||||
else
|
||||
mtmsr(mfmsr() | MSR_EE);
|
||||
}
|
||||
|
||||
extern void timer_interrupt(struct pt_regs *);
|
||||
extern void timer_broadcast_interrupt(void);
|
||||
extern void performance_monitor_exception(struct pt_regs *regs);
|
||||
extern void WatchdogException(struct pt_regs *regs);
|
||||
extern void unknown_exception(struct pt_regs *regs);
|
||||
static inline void __hard_irq_disable(void)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_BOOKE) || IS_ENABLED(CONFIG_40x))
|
||||
wrtee(0);
|
||||
else if (IS_ENABLED(CONFIG_PPC_8xx))
|
||||
wrtspr(SPRN_EID);
|
||||
else if (IS_ENABLED(CONFIG_PPC_BOOK3S_64))
|
||||
__mtmsrd(MSR_RI, 1);
|
||||
else
|
||||
mtmsr(mfmsr() & ~MSR_EE);
|
||||
}
|
||||
|
||||
static inline void __hard_EE_RI_disable(void)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_BOOKE) || IS_ENABLED(CONFIG_40x))
|
||||
wrtee(0);
|
||||
else if (IS_ENABLED(CONFIG_PPC_8xx))
|
||||
wrtspr(SPRN_NRI);
|
||||
else if (IS_ENABLED(CONFIG_PPC_BOOK3S_64))
|
||||
__mtmsrd(0, 1);
|
||||
else
|
||||
mtmsr(mfmsr() & ~(MSR_EE | MSR_RI));
|
||||
}
|
||||
|
||||
static inline void __hard_RI_enable(void)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_BOOKE) || IS_ENABLED(CONFIG_40x))
|
||||
return;
|
||||
|
||||
if (IS_ENABLED(CONFIG_PPC_8xx))
|
||||
wrtspr(SPRN_EID);
|
||||
else if (IS_ENABLED(CONFIG_PPC_BOOK3S_64))
|
||||
__mtmsrd(MSR_RI, 1);
|
||||
else
|
||||
mtmsr(mfmsr() | MSR_RI);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
#include <asm/paca.h>
|
||||
|
@ -221,18 +261,6 @@ static inline bool arch_irqs_disabled(void)
|
|||
|
||||
#endif /* CONFIG_PPC_BOOK3S */
|
||||
|
||||
#ifdef CONFIG_PPC_BOOK3E
|
||||
#define __hard_irq_enable() wrtee(MSR_EE)
|
||||
#define __hard_irq_disable() wrtee(0)
|
||||
#define __hard_EE_RI_disable() wrtee(0)
|
||||
#define __hard_RI_enable() do { } while (0)
|
||||
#else
|
||||
#define __hard_irq_enable() __mtmsrd(MSR_EE|MSR_RI, 1)
|
||||
#define __hard_irq_disable() __mtmsrd(MSR_RI, 1)
|
||||
#define __hard_EE_RI_disable() __mtmsrd(0, 1)
|
||||
#define __hard_RI_enable() __mtmsrd(MSR_RI, 1)
|
||||
#endif
|
||||
|
||||
#define hard_irq_disable() do { \
|
||||
unsigned long flags; \
|
||||
__hard_irq_disable(); \
|
||||
|
@ -296,8 +324,17 @@ extern void irq_set_pending_from_srr1(unsigned long srr1);
|
|||
|
||||
extern void force_external_irq_replay(void);
|
||||
|
||||
static inline void irq_soft_mask_regs_set_state(struct pt_regs *regs, unsigned long val)
|
||||
{
|
||||
regs->softe = val;
|
||||
}
|
||||
#else /* CONFIG_PPC64 */
|
||||
|
||||
static inline notrace unsigned long irq_soft_mask_return(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline unsigned long arch_local_save_flags(void)
|
||||
{
|
||||
return mfmsr();
|
||||
|
@ -327,22 +364,12 @@ static inline unsigned long arch_local_irq_save(void)
|
|||
|
||||
static inline void arch_local_irq_disable(void)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_BOOKE))
|
||||
wrtee(0);
|
||||
else if (IS_ENABLED(CONFIG_PPC_8xx))
|
||||
wrtspr(SPRN_EID);
|
||||
else
|
||||
mtmsr(mfmsr() & ~MSR_EE);
|
||||
__hard_irq_disable();
|
||||
}
|
||||
|
||||
static inline void arch_local_irq_enable(void)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_BOOKE))
|
||||
wrtee(MSR_EE);
|
||||
else if (IS_ENABLED(CONFIG_PPC_8xx))
|
||||
wrtspr(SPRN_EIE);
|
||||
else
|
||||
mtmsr(mfmsr() | MSR_EE);
|
||||
__hard_irq_enable();
|
||||
}
|
||||
|
||||
static inline bool arch_irqs_disabled_flags(unsigned long flags)
|
||||
|
@ -364,6 +391,9 @@ static inline bool arch_irq_disabled_regs(struct pt_regs *regs)
|
|||
|
||||
static inline void may_hard_irq_enable(void) { }
|
||||
|
||||
static inline void irq_soft_mask_regs_set_state(struct pt_regs *regs, unsigned long val)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_PPC64 */
|
||||
|
||||
#define ARCH_IRQ_INIT_FLAGS IRQ_NOREQUEST
|
||||
|
|
|
@ -0,0 +1,449 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
#ifndef _ASM_POWERPC_INTERRUPT_H
|
||||
#define _ASM_POWERPC_INTERRUPT_H
|
||||
|
||||
#include <linux/context_tracking.h>
|
||||
#include <linux/hardirq.h>
|
||||
#include <asm/cputime.h>
|
||||
#include <asm/ftrace.h>
|
||||
#include <asm/kprobes.h>
|
||||
#include <asm/runlatch.h>
|
||||
|
||||
struct interrupt_state {
|
||||
#ifdef CONFIG_PPC_BOOK3E_64
|
||||
enum ctx_state ctx_state;
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline void booke_restore_dbcr0(void)
|
||||
{
|
||||
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
|
||||
unsigned long dbcr0 = current->thread.debug.dbcr0;
|
||||
|
||||
if (IS_ENABLED(CONFIG_PPC32) && unlikely(dbcr0 & DBCR0_IDM)) {
|
||||
mtspr(SPRN_DBSR, -1);
|
||||
mtspr(SPRN_DBCR0, global_dbcr0[smp_processor_id()]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void interrupt_enter_prepare(struct pt_regs *regs, struct interrupt_state *state)
|
||||
{
|
||||
/*
|
||||
* Book3E reconciles irq soft mask in asm
|
||||
*/
|
||||
#ifdef CONFIG_PPC_BOOK3S_64
|
||||
if (irq_soft_mask_set_return(IRQS_ALL_DISABLED) == IRQS_ENABLED)
|
||||
trace_hardirqs_off();
|
||||
local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
|
||||
|
||||
if (user_mode(regs)) {
|
||||
CT_WARN_ON(ct_state() != CONTEXT_USER);
|
||||
user_exit_irqoff();
|
||||
|
||||
account_cpu_user_entry();
|
||||
account_stolen_time();
|
||||
} else {
|
||||
/*
|
||||
* CT_WARN_ON comes here via program_check_exception,
|
||||
* so avoid recursion.
|
||||
*/
|
||||
if (TRAP(regs) != 0x700)
|
||||
CT_WARN_ON(ct_state() != CONTEXT_KERNEL);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PPC_BOOK3E_64
|
||||
state->ctx_state = exception_enter();
|
||||
if (user_mode(regs))
|
||||
account_cpu_user_entry();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Care should be taken to note that interrupt_exit_prepare and
|
||||
* interrupt_async_exit_prepare do not necessarily return immediately to
|
||||
* regs context (e.g., if regs is usermode, we don't necessarily return to
|
||||
* user mode). Other interrupts might be taken between here and return,
|
||||
* context switch / preemption may occur in the exit path after this, or a
|
||||
* signal may be delivered, etc.
|
||||
*
|
||||
* The real interrupt exit code is platform specific, e.g.,
|
||||
* interrupt_exit_user_prepare / interrupt_exit_kernel_prepare for 64s.
|
||||
*
|
||||
* However interrupt_nmi_exit_prepare does return directly to regs, because
|
||||
* NMIs do not do "exit work" or replay soft-masked interrupts.
|
||||
*/
|
||||
static inline void interrupt_exit_prepare(struct pt_regs *regs, struct interrupt_state *state)
|
||||
{
|
||||
#ifdef CONFIG_PPC_BOOK3E_64
|
||||
exception_exit(state->ctx_state);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Book3S exits to user via interrupt_exit_user_prepare(), which does
|
||||
* context tracking, which is a cleaner way to handle PREEMPT=y
|
||||
* and avoid context entry/exit in e.g., preempt_schedule_irq()),
|
||||
* which is likely to be where the core code wants to end up.
|
||||
*
|
||||
* The above comment explains why we can't do the
|
||||
*
|
||||
* if (user_mode(regs))
|
||||
* user_exit_irqoff();
|
||||
*
|
||||
* sequence here.
|
||||
*/
|
||||
}
|
||||
|
||||
static inline void interrupt_async_enter_prepare(struct pt_regs *regs, struct interrupt_state *state)
|
||||
{
|
||||
#ifdef CONFIG_PPC_BOOK3S_64
|
||||
if (cpu_has_feature(CPU_FTR_CTRL) &&
|
||||
!test_thread_local_flags(_TLF_RUNLATCH))
|
||||
__ppc64_runlatch_on();
|
||||
#endif
|
||||
|
||||
interrupt_enter_prepare(regs, state);
|
||||
irq_enter();
|
||||
}
|
||||
|
||||
static inline void interrupt_async_exit_prepare(struct pt_regs *regs, struct interrupt_state *state)
|
||||
{
|
||||
irq_exit();
|
||||
interrupt_exit_prepare(regs, state);
|
||||
}
|
||||
|
||||
struct interrupt_nmi_state {
|
||||
#ifdef CONFIG_PPC64
|
||||
#ifdef CONFIG_PPC_BOOK3S_64
|
||||
u8 irq_soft_mask;
|
||||
u8 irq_happened;
|
||||
#endif
|
||||
u8 ftrace_enabled;
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline void interrupt_nmi_enter_prepare(struct pt_regs *regs, struct interrupt_nmi_state *state)
|
||||
{
|
||||
#ifdef CONFIG_PPC64
|
||||
#ifdef CONFIG_PPC_BOOK3S_64
|
||||
state->irq_soft_mask = local_paca->irq_soft_mask;
|
||||
state->irq_happened = local_paca->irq_happened;
|
||||
|
||||
/*
|
||||
* Set IRQS_ALL_DISABLED unconditionally so irqs_disabled() does
|
||||
* the right thing, and set IRQ_HARD_DIS. We do not want to reconcile
|
||||
* because that goes through irq tracing which we don't want in NMI.
|
||||
*/
|
||||
local_paca->irq_soft_mask = IRQS_ALL_DISABLED;
|
||||
local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
|
||||
|
||||
/* Don't do any per-CPU operations until interrupt state is fixed */
|
||||
#endif
|
||||
/* Allow DEC and PMI to be traced when they are soft-NMI */
|
||||
if (TRAP(regs) != 0x900 && TRAP(regs) != 0xf00 && TRAP(regs) != 0x260) {
|
||||
state->ftrace_enabled = this_cpu_get_ftrace_enabled();
|
||||
this_cpu_set_ftrace_enabled(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Do not use nmi_enter() for pseries hash guest taking a real-mode
|
||||
* NMI because not everything it touches is within the RMA limit.
|
||||
*/
|
||||
if (!IS_ENABLED(CONFIG_PPC_BOOK3S_64) ||
|
||||
!firmware_has_feature(FW_FEATURE_LPAR) ||
|
||||
radix_enabled() || (mfmsr() & MSR_DR))
|
||||
nmi_enter();
|
||||
}
|
||||
|
||||
static inline void interrupt_nmi_exit_prepare(struct pt_regs *regs, struct interrupt_nmi_state *state)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_PPC_BOOK3S_64) ||
|
||||
!firmware_has_feature(FW_FEATURE_LPAR) ||
|
||||
radix_enabled() || (mfmsr() & MSR_DR))
|
||||
nmi_exit();
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
if (TRAP(regs) != 0x900 && TRAP(regs) != 0xf00 && TRAP(regs) != 0x260)
|
||||
this_cpu_set_ftrace_enabled(state->ftrace_enabled);
|
||||
|
||||
#ifdef CONFIG_PPC_BOOK3S_64
|
||||
/* Check we didn't change the pending interrupt mask. */
|
||||
WARN_ON_ONCE((state->irq_happened | PACA_IRQ_HARD_DIS) != local_paca->irq_happened);
|
||||
local_paca->irq_happened = state->irq_happened;
|
||||
local_paca->irq_soft_mask = state->irq_soft_mask;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't use noinstr here like x86, but rather add NOKPROBE_SYMBOL to each
|
||||
* function definition. The reason for this is the noinstr section is placed
|
||||
* after the main text section, i.e., very far away from the interrupt entry
|
||||
* asm. That creates problems with fitting linker stubs when building large
|
||||
* kernels.
|
||||
*/
|
||||
#define interrupt_handler __visible noinline notrace __no_kcsan __no_sanitize_address
|
||||
|
||||
/**
|
||||
* DECLARE_INTERRUPT_HANDLER_RAW - Declare raw interrupt handler function
|
||||
* @func: Function name of the entry point
|
||||
* @returns: Returns a value back to asm caller
|
||||
*/
|
||||
#define DECLARE_INTERRUPT_HANDLER_RAW(func) \
|
||||
__visible long func(struct pt_regs *regs)
|
||||
|
||||
/**
|
||||
* DEFINE_INTERRUPT_HANDLER_RAW - Define raw interrupt handler function
|
||||
* @func: Function name of the entry point
|
||||
* @returns: Returns a value back to asm caller
|
||||
*
|
||||
* @func is called from ASM entry code.
|
||||
*
|
||||
* This is a plain function which does no tracing, reconciling, etc.
|
||||
* The macro is written so it acts as function definition. Append the
|
||||
* body with a pair of curly brackets.
|
||||
*
|
||||
* raw interrupt handlers must not enable or disable interrupts, or
|
||||
* schedule, tracing and instrumentation (ftrace, lockdep, etc) would
|
||||
* not be advisable either, although may be possible in a pinch, the
|
||||
* trace will look odd at least.
|
||||
*
|
||||
* A raw handler may call one of the other interrupt handler functions
|
||||
* to be converted into that interrupt context without these restrictions.
|
||||
*
|
||||
* On PPC64, _RAW handlers may return with fast_interrupt_return.
|
||||
*
|
||||
* Specific handlers may have additional restrictions.
|
||||
*/
|
||||
#define DEFINE_INTERRUPT_HANDLER_RAW(func) \
|
||||
static __always_inline long ____##func(struct pt_regs *regs); \
|
||||
\
|
||||
interrupt_handler long func(struct pt_regs *regs) \
|
||||
{ \
|
||||
long ret; \
|
||||
\
|
||||
ret = ____##func (regs); \
|
||||
\
|
||||
return ret; \
|
||||
} \
|
||||
NOKPROBE_SYMBOL(func); \
|
||||
\
|
||||
static __always_inline long ____##func(struct pt_regs *regs)
|
||||
|
||||
/**
|
||||
* DECLARE_INTERRUPT_HANDLER - Declare synchronous interrupt handler function
|
||||
* @func: Function name of the entry point
|
||||
*/
|
||||
#define DECLARE_INTERRUPT_HANDLER(func) \
|
||||
__visible void func(struct pt_regs *regs)
|
||||
|
||||
/**
|
||||
* DEFINE_INTERRUPT_HANDLER - Define synchronous interrupt handler function
|
||||
* @func: Function name of the entry point
|
||||
*
|
||||
* @func is called from ASM entry code.
|
||||
*
|
||||
* The macro is written so it acts as function definition. Append the
|
||||
* body with a pair of curly brackets.
|
||||
*/
|
||||
#define DEFINE_INTERRUPT_HANDLER(func) \
|
||||
static __always_inline void ____##func(struct pt_regs *regs); \
|
||||
\
|
||||
interrupt_handler void func(struct pt_regs *regs) \
|
||||
{ \
|
||||
struct interrupt_state state; \
|
||||
\
|
||||
interrupt_enter_prepare(regs, &state); \
|
||||
\
|
||||
____##func (regs); \
|
||||
\
|
||||
interrupt_exit_prepare(regs, &state); \
|
||||
} \
|
||||
NOKPROBE_SYMBOL(func); \
|
||||
\
|
||||
static __always_inline void ____##func(struct pt_regs *regs)
|
||||
|
||||
/**
|
||||
* DECLARE_INTERRUPT_HANDLER_RET - Declare synchronous interrupt handler function
|
||||
* @func: Function name of the entry point
|
||||
* @returns: Returns a value back to asm caller
|
||||
*/
|
||||
#define DECLARE_INTERRUPT_HANDLER_RET(func) \
|
||||
__visible long func(struct pt_regs *regs)
|
||||
|
||||
/**
|
||||
* DEFINE_INTERRUPT_HANDLER_RET - Define synchronous interrupt handler function
|
||||
* @func: Function name of the entry point
|
||||
* @returns: Returns a value back to asm caller
|
||||
*
|
||||
* @func is called from ASM entry code.
|
||||
*
|
||||
* The macro is written so it acts as function definition. Append the
|
||||
* body with a pair of curly brackets.
|
||||
*/
|
||||
#define DEFINE_INTERRUPT_HANDLER_RET(func) \
|
||||
static __always_inline long ____##func(struct pt_regs *regs); \
|
||||
\
|
||||
interrupt_handler long func(struct pt_regs *regs) \
|
||||
{ \
|
||||
struct interrupt_state state; \
|
||||
long ret; \
|
||||
\
|
||||
interrupt_enter_prepare(regs, &state); \
|
||||
\
|
||||
ret = ____##func (regs); \
|
||||
\
|
||||
interrupt_exit_prepare(regs, &state); \
|
||||
\
|
||||
return ret; \
|
||||
} \
|
||||
NOKPROBE_SYMBOL(func); \
|
||||
\
|
||||
static __always_inline long ____##func(struct pt_regs *regs)
|
||||
|
||||
/**
|
||||
* DECLARE_INTERRUPT_HANDLER_ASYNC - Declare asynchronous interrupt handler function
|
||||
* @func: Function name of the entry point
|
||||
*/
|
||||
#define DECLARE_INTERRUPT_HANDLER_ASYNC(func) \
|
||||
__visible void func(struct pt_regs *regs)
|
||||
|
||||
/**
|
||||
* DEFINE_INTERRUPT_HANDLER_ASYNC - Define asynchronous interrupt handler function
|
||||
* @func: Function name of the entry point
|
||||
*
|
||||
* @func is called from ASM entry code.
|
||||
*
|
||||
* The macro is written so it acts as function definition. Append the
|
||||
* body with a pair of curly brackets.
|
||||
*/
|
||||
#define DEFINE_INTERRUPT_HANDLER_ASYNC(func) \
|
||||
static __always_inline void ____##func(struct pt_regs *regs); \
|
||||
\
|
||||
interrupt_handler void func(struct pt_regs *regs) \
|
||||
{ \
|
||||
struct interrupt_state state; \
|
||||
\
|
||||
interrupt_async_enter_prepare(regs, &state); \
|
||||
\
|
||||
____##func (regs); \
|
||||
\
|
||||
interrupt_async_exit_prepare(regs, &state); \
|
||||
} \
|
||||
NOKPROBE_SYMBOL(func); \
|
||||
\
|
||||
static __always_inline void ____##func(struct pt_regs *regs)
|
||||
|
||||
/**
|
||||
* DECLARE_INTERRUPT_HANDLER_NMI - Declare NMI interrupt handler function
|
||||
* @func: Function name of the entry point
|
||||
* @returns: Returns a value back to asm caller
|
||||
*/
|
||||
#define DECLARE_INTERRUPT_HANDLER_NMI(func) \
|
||||
__visible long func(struct pt_regs *regs)
|
||||
|
||||
/**
|
||||
* DEFINE_INTERRUPT_HANDLER_NMI - Define NMI interrupt handler function
|
||||
* @func: Function name of the entry point
|
||||
* @returns: Returns a value back to asm caller
|
||||
*
|
||||
* @func is called from ASM entry code.
|
||||
*
|
||||
* The macro is written so it acts as function definition. Append the
|
||||
* body with a pair of curly brackets.
|
||||
*/
|
||||
#define DEFINE_INTERRUPT_HANDLER_NMI(func) \
|
||||
static __always_inline long ____##func(struct pt_regs *regs); \
|
||||
\
|
||||
interrupt_handler long func(struct pt_regs *regs) \
|
||||
{ \
|
||||
struct interrupt_nmi_state state; \
|
||||
long ret; \
|
||||
\
|
||||
interrupt_nmi_enter_prepare(regs, &state); \
|
||||
\
|
||||
ret = ____##func (regs); \
|
||||
\
|
||||
interrupt_nmi_exit_prepare(regs, &state); \
|
||||
\
|
||||
return ret; \
|
||||
} \
|
||||
NOKPROBE_SYMBOL(func); \
|
||||
\
|
||||
static __always_inline long ____##func(struct pt_regs *regs)
|
||||
|
||||
|
||||
/* Interrupt handlers */
|
||||
/* kernel/traps.c */
|
||||
DECLARE_INTERRUPT_HANDLER_NMI(system_reset_exception);
|
||||
#ifdef CONFIG_PPC_BOOK3S_64
|
||||
DECLARE_INTERRUPT_HANDLER_ASYNC(machine_check_exception);
|
||||
#else
|
||||
DECLARE_INTERRUPT_HANDLER_NMI(machine_check_exception);
|
||||
#endif
|
||||
DECLARE_INTERRUPT_HANDLER(SMIException);
|
||||
DECLARE_INTERRUPT_HANDLER(handle_hmi_exception);
|
||||
DECLARE_INTERRUPT_HANDLER(unknown_exception);
|
||||
DECLARE_INTERRUPT_HANDLER_ASYNC(unknown_async_exception);
|
||||
DECLARE_INTERRUPT_HANDLER(instruction_breakpoint_exception);
|
||||
DECLARE_INTERRUPT_HANDLER(RunModeException);
|
||||
DECLARE_INTERRUPT_HANDLER(single_step_exception);
|
||||
DECLARE_INTERRUPT_HANDLER(program_check_exception);
|
||||
DECLARE_INTERRUPT_HANDLER(emulation_assist_interrupt);
|
||||
DECLARE_INTERRUPT_HANDLER(alignment_exception);
|
||||
DECLARE_INTERRUPT_HANDLER(StackOverflow);
|
||||
DECLARE_INTERRUPT_HANDLER(stack_overflow_exception);
|
||||
DECLARE_INTERRUPT_HANDLER(kernel_fp_unavailable_exception);
|
||||
DECLARE_INTERRUPT_HANDLER(altivec_unavailable_exception);
|
||||
DECLARE_INTERRUPT_HANDLER(vsx_unavailable_exception);
|
||||
DECLARE_INTERRUPT_HANDLER(facility_unavailable_exception);
|
||||
DECLARE_INTERRUPT_HANDLER(fp_unavailable_tm);
|
||||
DECLARE_INTERRUPT_HANDLER(altivec_unavailable_tm);
|
||||
DECLARE_INTERRUPT_HANDLER(vsx_unavailable_tm);
|
||||
DECLARE_INTERRUPT_HANDLER_NMI(performance_monitor_exception_nmi);
|
||||
DECLARE_INTERRUPT_HANDLER_ASYNC(performance_monitor_exception_async);
|
||||
DECLARE_INTERRUPT_HANDLER_RAW(performance_monitor_exception);
|
||||
DECLARE_INTERRUPT_HANDLER(DebugException);
|
||||
DECLARE_INTERRUPT_HANDLER(altivec_assist_exception);
|
||||
DECLARE_INTERRUPT_HANDLER(CacheLockingException);
|
||||
DECLARE_INTERRUPT_HANDLER(SPEFloatingPointException);
|
||||
DECLARE_INTERRUPT_HANDLER(SPEFloatingPointRoundException);
|
||||
DECLARE_INTERRUPT_HANDLER(unrecoverable_exception);
|
||||
DECLARE_INTERRUPT_HANDLER(WatchdogException);
|
||||
DECLARE_INTERRUPT_HANDLER(kernel_bad_stack);
|
||||
|
||||
/* slb.c */
|
||||
DECLARE_INTERRUPT_HANDLER_RAW(do_slb_fault);
|
||||
DECLARE_INTERRUPT_HANDLER(do_bad_slb_fault);
|
||||
|
||||
/* hash_utils.c */
|
||||
DECLARE_INTERRUPT_HANDLER_RAW(do_hash_fault);
|
||||
|
||||
/* fault.c */
|
||||
DECLARE_INTERRUPT_HANDLER_RET(do_page_fault);
|
||||
DECLARE_INTERRUPT_HANDLER(do_bad_page_fault_segv);
|
||||
|
||||
/* process.c */
|
||||
DECLARE_INTERRUPT_HANDLER(do_break);
|
||||
|
||||
/* time.c */
|
||||
DECLARE_INTERRUPT_HANDLER_ASYNC(timer_interrupt);
|
||||
|
||||
/* mce.c */
|
||||
DECLARE_INTERRUPT_HANDLER_NMI(machine_check_early);
|
||||
DECLARE_INTERRUPT_HANDLER_NMI(hmi_exception_realmode);
|
||||
|
||||
DECLARE_INTERRUPT_HANDLER_ASYNC(TAUException);
|
||||
|
||||
void replay_system_reset(void);
|
||||
void replay_soft_interrupts(void);
|
||||
|
||||
static inline void interrupt_cond_local_irq_enable(struct pt_regs *regs)
|
||||
{
|
||||
if (!arch_irq_disabled_regs(regs))
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
#endif /* _ASM_POWERPC_INTERRUPT_H */
|
|
@ -136,6 +136,7 @@ int load_crashdump_segments_ppc64(struct kimage *image,
|
|||
int setup_purgatory_ppc64(struct kimage *image, const void *slave_code,
|
||||
const void *fdt, unsigned long kernel_load_addr,
|
||||
unsigned long fdt_load_addr);
|
||||
unsigned int kexec_fdt_totalsize_ppc64(struct kimage *image);
|
||||
int setup_new_fdt_ppc64(const struct kimage *image, void *fdt,
|
||||
unsigned long initrd_load_addr,
|
||||
unsigned long initrd_len, const char *cmdline);
|
||||
|
|
|
@ -91,6 +91,7 @@ static __always_inline void setup_kup(void)
|
|||
|
||||
static inline void allow_read_from_user(const void __user *from, unsigned long size)
|
||||
{
|
||||
barrier_nospec();
|
||||
allow_user_access(NULL, from, size, KUAP_READ);
|
||||
}
|
||||
|
||||
|
@ -102,6 +103,7 @@ static inline void allow_write_to_user(void __user *to, unsigned long size)
|
|||
static inline void allow_read_write_user(void __user *to, const void __user *from,
|
||||
unsigned long size)
|
||||
{
|
||||
barrier_nospec();
|
||||
allow_user_access(to, from, size, KUAP_READ_WRITE);
|
||||
}
|
||||
|
||||
|
|
|
@ -277,6 +277,13 @@ extern int kvmppc_hcall_impl_hv_realmode(unsigned long cmd);
|
|||
extern void kvmppc_copy_to_svcpu(struct kvm_vcpu *vcpu);
|
||||
extern void kvmppc_copy_from_svcpu(struct kvm_vcpu *vcpu);
|
||||
|
||||
long kvmppc_read_intr(void);
|
||||
void kvmppc_bad_interrupt(struct pt_regs *regs);
|
||||
void kvmhv_p9_set_lpcr(struct kvm_split_mode *sip);
|
||||
void kvmhv_p9_restore_lpcr(struct kvm_split_mode *sip);
|
||||
void kvmppc_set_msr_hv(struct kvm_vcpu *vcpu, u64 msr);
|
||||
void kvmppc_inject_interrupt_hv(struct kvm_vcpu *vcpu, int vec, u64 srr1_flags);
|
||||
|
||||
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
||||
void kvmppc_save_tm_pr(struct kvm_vcpu *vcpu);
|
||||
void kvmppc_restore_tm_pr(struct kvm_vcpu *vcpu);
|
||||
|
|
|
@ -629,9 +629,9 @@ extern int h_ipi_redirect;
|
|||
static inline struct kvmppc_passthru_irqmap *kvmppc_get_passthru_irqmap(
|
||||
struct kvm *kvm)
|
||||
{ return NULL; }
|
||||
static inline void kvmppc_alloc_host_rm_ops(void) {};
|
||||
static inline void kvmppc_free_host_rm_ops(void) {};
|
||||
static inline void kvmppc_free_pimap(struct kvm *kvm) {};
|
||||
static inline void kvmppc_alloc_host_rm_ops(void) {}
|
||||
static inline void kvmppc_free_host_rm_ops(void) {}
|
||||
static inline void kvmppc_free_pimap(struct kvm *kvm) {}
|
||||
static inline int kvmppc_xics_rm_complete(struct kvm_vcpu *vcpu, u32 hcall)
|
||||
{ return 0; }
|
||||
static inline int kvmppc_xics_enabled(struct kvm_vcpu *vcpu)
|
||||
|
@ -883,9 +883,9 @@ static inline void kvmppc_mmu_flush_icache(kvm_pfn_t pfn)
|
|||
|
||||
/* Clear i-cache for new pages */
|
||||
page = pfn_to_page(pfn);
|
||||
if (!test_bit(PG_arch_1, &page->flags)) {
|
||||
if (!test_bit(PG_dcache_clean, &page->flags)) {
|
||||
flush_dcache_icache_page(page);
|
||||
set_bit(PG_arch_1, &page->flags);
|
||||
set_bit(PG_dcache_clean, &page->flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -59,6 +59,9 @@ struct machdep_calls {
|
|||
int (*pcibios_root_bridge_prepare)(struct pci_host_bridge
|
||||
*bridge);
|
||||
|
||||
/* finds all the pci_controllers present at boot */
|
||||
void (*discover_phbs)(void);
|
||||
|
||||
/* To setup PHBs when using automatic OF platform driver for PCI */
|
||||
int (*pci_setup_phb)(struct pci_controller *host);
|
||||
|
||||
|
|
|
@ -204,7 +204,18 @@ struct mce_error_info {
|
|||
bool ignore_event;
|
||||
};
|
||||
|
||||
#define MAX_MC_EVT 100
|
||||
#define MAX_MC_EVT 10
|
||||
|
||||
struct mce_info {
|
||||
int mce_nest_count;
|
||||
struct machine_check_event mce_event[MAX_MC_EVT];
|
||||
/* Queue for delayed MCE events. */
|
||||
int mce_queue_count;
|
||||
struct machine_check_event mce_event_queue[MAX_MC_EVT];
|
||||
/* Queue for delayed MCE UE events. */
|
||||
int mce_ue_count;
|
||||
struct machine_check_event mce_ue_event_queue[MAX_MC_EVT];
|
||||
};
|
||||
|
||||
/* Release flags for get_mce_event() */
|
||||
#define MCE_EVENT_RELEASE true
|
||||
|
@ -234,4 +245,11 @@ long __machine_check_early_realmode_p8(struct pt_regs *regs);
|
|||
long __machine_check_early_realmode_p9(struct pt_regs *regs);
|
||||
long __machine_check_early_realmode_p10(struct pt_regs *regs);
|
||||
#endif /* CONFIG_PPC_BOOK3S_64 */
|
||||
|
||||
#ifdef CONFIG_PPC_BOOK3S_64
|
||||
void mce_init(void);
|
||||
#else
|
||||
static inline void mce_init(void) { };
|
||||
#endif /* CONFIG_PPC_BOOK3S_64 */
|
||||
|
||||
#endif /* __ASM_PPC64_MCE_H__ */
|
||||
|
|
|
@ -282,9 +282,6 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma,
|
|||
}
|
||||
|
||||
#define pkey_mm_init(mm)
|
||||
#define thread_pkey_regs_save(thread)
|
||||
#define thread_pkey_regs_restore(new_thread, old_thread)
|
||||
#define thread_pkey_regs_init(thread)
|
||||
#define arch_dup_pkeys(oldmm, mm)
|
||||
|
||||
static inline u64 pte_to_hpte_pkey_bits(u64 pteflags, unsigned long flags)
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#ifdef CONFIG_PPC_WATCHDOG
|
||||
extern void arch_touch_nmi_watchdog(void);
|
||||
long soft_nmi_interrupt(struct pt_regs *regs);
|
||||
#else
|
||||
static inline void arch_touch_nmi_watchdog(void) {}
|
||||
#endif
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <asm/hmi.h>
|
||||
#include <asm/cpuidle.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/mce.h>
|
||||
|
||||
#include <asm-generic/mmiowb_types.h>
|
||||
|
||||
|
@ -108,8 +109,7 @@ struct paca_struct {
|
|||
*/
|
||||
/* used for most interrupts/exceptions */
|
||||
u64 exgen[EX_SIZE] __attribute__((aligned(0x80)));
|
||||
u64 exslb[EX_SIZE]; /* used for SLB/segment table misses
|
||||
* on the linear mapping */
|
||||
|
||||
/* SLB related definitions */
|
||||
u16 vmalloc_sllp;
|
||||
u8 slb_cache_ptr;
|
||||
|
@ -273,6 +273,9 @@ struct paca_struct {
|
|||
#ifdef CONFIG_MMIOWB
|
||||
struct mmiowb_state mmiowb_state;
|
||||
#endif
|
||||
#ifdef CONFIG_PPC_BOOK3S_64
|
||||
struct mce_info *mce_info;
|
||||
#endif /* CONFIG_PPC_BOOK3S_64 */
|
||||
} ____cacheline_aligned;
|
||||
|
||||
extern void copy_mm_to_paca(struct mm_struct *mm);
|
||||
|
@ -285,9 +288,9 @@ extern void free_unused_pacas(void);
|
|||
|
||||
#else /* CONFIG_PPC64 */
|
||||
|
||||
static inline void allocate_paca_ptrs(void) { };
|
||||
static inline void allocate_paca(int cpu) { };
|
||||
static inline void free_unused_pacas(void) { };
|
||||
static inline void allocate_paca_ptrs(void) { }
|
||||
static inline void allocate_paca(int cpu) { }
|
||||
static inline void free_unused_pacas(void) { }
|
||||
|
||||
#endif /* CONFIG_PPC64 */
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_PPC_SPLPAR
|
||||
#include <linux/smp.h>
|
||||
#include <asm/kvm_guest.h>
|
||||
#include <asm/cputhreads.h>
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <asm/perf_event_server.h>
|
||||
#else
|
||||
static inline bool is_sier_available(void) { return false; }
|
||||
static inline unsigned long get_pmcs_ext_regs(int idx) { return 0; }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FSL_EMB_PERF_EVENT
|
||||
|
@ -40,6 +41,7 @@ static inline bool is_sier_available(void) { return false; }
|
|||
|
||||
/* To support perf_regs sier update */
|
||||
extern bool is_sier_available(void);
|
||||
extern unsigned long get_pmcs_ext_regs(int idx);
|
||||
/* To define perf extended regs mask value */
|
||||
extern u64 PERF_REG_EXTENDED_MASK;
|
||||
#define PERF_REG_EXTENDED_MASK PERF_REG_EXTENDED_MASK
|
||||
|
|
|
@ -36,9 +36,9 @@ struct power_pmu {
|
|||
unsigned long test_adder;
|
||||
int (*compute_mmcr)(u64 events[], int n_ev,
|
||||
unsigned int hwc[], struct mmcr_regs *mmcr,
|
||||
struct perf_event *pevents[]);
|
||||
struct perf_event *pevents[], u32 flags);
|
||||
int (*get_constraint)(u64 event_id, unsigned long *mskp,
|
||||
unsigned long *valp);
|
||||
unsigned long *valp, u64 event_config1);
|
||||
int (*get_alternatives)(u64 event_id, unsigned int flags,
|
||||
u64 alt[]);
|
||||
void (*get_mem_data_src)(union perf_mem_data_src *dsrc,
|
||||
|
@ -83,6 +83,7 @@ struct power_pmu {
|
|||
#define PPMU_NO_SIAR 0x00000100 /* Do not use SIAR */
|
||||
#define PPMU_ARCH_31 0x00000200 /* Has MMCR3, SIER2 and SIER3 */
|
||||
#define PPMU_P10_DD1 0x00000400 /* Is power10 DD1 processor version */
|
||||
#define PPMU_HAS_ATTR_CONFIG1 0x00000800 /* Using config1 attribute */
|
||||
|
||||
/*
|
||||
* Values for flags to get_alternatives()
|
||||
|
|
|
@ -162,6 +162,9 @@ static inline bool is_ioremap_addr(const void *x)
|
|||
|
||||
return addr >= IOREMAP_BASE && addr < IOREMAP_END;
|
||||
}
|
||||
|
||||
struct seq_file;
|
||||
void arch_report_meminfo(struct seq_file *m);
|
||||
#endif /* CONFIG_PPC64 */
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
|
|
@ -169,10 +169,4 @@ static inline bool arch_pkeys_enabled(void)
|
|||
}
|
||||
|
||||
extern void pkey_mm_init(struct mm_struct *mm);
|
||||
extern bool arch_supports_pkeys(int cap);
|
||||
extern unsigned int arch_usable_pkeys(void);
|
||||
extern void thread_pkey_regs_save(struct thread_struct *thread);
|
||||
extern void thread_pkey_regs_restore(struct thread_struct *new_thread,
|
||||
struct thread_struct *old_thread);
|
||||
extern void thread_pkey_regs_init(struct thread_struct *thread);
|
||||
#endif /*_ASM_POWERPC_KEYS_H */
|
||||
|
|
|
@ -13,10 +13,6 @@
|
|||
|
||||
extern unsigned long isa_io_base;
|
||||
|
||||
extern void pci_setup_phb_io(struct pci_controller *hose, int primary);
|
||||
extern void pci_setup_phb_io_dynamic(struct pci_controller *hose, int primary);
|
||||
|
||||
|
||||
extern struct list_head hose_list;
|
||||
|
||||
extern struct pci_dev *isa_bridge_pcidev; /* may be NULL if no ISA bus */
|
||||
|
@ -32,9 +28,6 @@ struct pci_dn;
|
|||
void *pci_traverse_device_nodes(struct device_node *start,
|
||||
void *(*fn)(struct device_node *, void *),
|
||||
void *data);
|
||||
void *traverse_pci_dn(struct pci_dn *root,
|
||||
void *(*fn)(struct pci_dn *, void *),
|
||||
void *data);
|
||||
extern void pci_devs_phb_init_dynamic(struct pci_controller *phb);
|
||||
|
||||
/* From rtas_pci.h */
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
|
||||
#define ACCOUNT_CPU_USER_ENTRY(ptr, ra, rb)
|
||||
#define ACCOUNT_CPU_USER_EXIT(ptr, ra, rb)
|
||||
#define ACCOUNT_STOLEN_TIME
|
||||
#else
|
||||
#define ACCOUNT_CPU_USER_ENTRY(ptr, ra, rb) \
|
||||
MFTB(ra); /* get timebase */ \
|
||||
|
@ -44,29 +43,6 @@
|
|||
PPC_LL ra, ACCOUNT_SYSTEM_TIME(ptr); \
|
||||
add ra,ra,rb; /* add on to system time */ \
|
||||
PPC_STL ra, ACCOUNT_SYSTEM_TIME(ptr)
|
||||
|
||||
#ifdef CONFIG_PPC_SPLPAR
|
||||
#define ACCOUNT_STOLEN_TIME \
|
||||
BEGIN_FW_FTR_SECTION; \
|
||||
beq 33f; \
|
||||
/* from user - see if there are any DTL entries to process */ \
|
||||
ld r10,PACALPPACAPTR(r13); /* get ptr to VPA */ \
|
||||
ld r11,PACA_DTL_RIDX(r13); /* get log read index */ \
|
||||
addi r10,r10,LPPACA_DTLIDX; \
|
||||
LDX_BE r10,0,r10; /* get log write index */ \
|
||||
cmpd cr1,r11,r10; \
|
||||
beq+ cr1,33f; \
|
||||
bl accumulate_stolen_time; \
|
||||
ld r12,_MSR(r1); \
|
||||
andi. r10,r12,MSR_PR; /* Restore cr0 (coming from user) */ \
|
||||
33: \
|
||||
END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR)
|
||||
|
||||
#else /* CONFIG_PPC_SPLPAR */
|
||||
#define ACCOUNT_STOLEN_TIME
|
||||
|
||||
#endif /* CONFIG_PPC_SPLPAR */
|
||||
|
||||
#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
|
||||
|
||||
/*
|
||||
|
|
|
@ -70,6 +70,9 @@ struct pt_regs
|
|||
};
|
||||
#endif
|
||||
|
||||
|
||||
#define STACK_FRAME_WITH_PT_REGS (STACK_FRAME_OVERHEAD + sizeof(struct pt_regs))
|
||||
|
||||
#ifdef __powerpc64__
|
||||
|
||||
/*
|
||||
|
@ -229,6 +232,11 @@ static inline bool trap_is_scv(struct pt_regs *regs)
|
|||
return (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && TRAP(regs) == 0x3000);
|
||||
}
|
||||
|
||||
static inline bool trap_is_unsupported_scv(struct pt_regs *regs)
|
||||
{
|
||||
return IS_ENABLED(CONFIG_PPC_BOOK3S_64) && TRAP(regs) == 0x7ff0;
|
||||
}
|
||||
|
||||
static inline bool trap_is_syscall(struct pt_regs *regs)
|
||||
{
|
||||
return (trap_is_scv(regs) || TRAP(regs) == 0xc00);
|
||||
|
|
|
@ -1375,6 +1375,7 @@
|
|||
#define mtmsr(v) asm volatile("mtmsr %0" : \
|
||||
: "r" ((unsigned long)(v)) \
|
||||
: "memory")
|
||||
#define __mtmsrd(v, l) BUILD_BUG()
|
||||
#define __MTMSR "mtmsr"
|
||||
#endif
|
||||
|
||||
|
@ -1413,13 +1414,24 @@ static inline void msr_check_and_clear(unsigned long bits)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_PPC32
|
||||
#define mfsrin(v) ({unsigned int rval; \
|
||||
asm volatile("mfsrin %0,%1" : "=r" (rval) : "r" (v)); \
|
||||
rval;})
|
||||
|
||||
static inline void mtsrin(u32 val, u32 idx)
|
||||
static inline u32 mfsr(u32 idx)
|
||||
{
|
||||
asm volatile("mtsrin %0, %1" : : "r" (val), "r" (idx));
|
||||
u32 val;
|
||||
|
||||
if (__builtin_constant_p(idx))
|
||||
asm volatile("mfsr %0, %1" : "=r" (val): "i" (idx >> 28));
|
||||
else
|
||||
asm volatile("mfsrin %0, %1" : "=r" (val): "r" (idx));
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline void mtsr(u32 val, u32 idx)
|
||||
{
|
||||
if (__builtin_constant_p(idx))
|
||||
asm volatile("mtsr %1, %0" : : "r" (val), "i" (idx >> 28));
|
||||
else
|
||||
asm volatile("mtsrin %0, %1" : : "r" (val), "r" (idx));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -691,6 +691,9 @@
|
|||
#define mttmr(rn, v) asm volatile(MTTMR(rn, %0) : \
|
||||
: "r" ((unsigned long)(v)) \
|
||||
: "memory")
|
||||
|
||||
extern unsigned long global_dbcr0[];
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* __ASM_POWERPC_REG_BOOKE_H__ */
|
||||
|
|
|
@ -369,7 +369,7 @@ void rtas_initialize(void);
|
|||
#else
|
||||
static inline int page_is_rtas_user_buf(unsigned long pfn) { return 0;}
|
||||
static inline void pSeries_coalesce_init(void) { }
|
||||
static inline void rtas_initialize(void) { };
|
||||
static inline void rtas_initialize(void) { }
|
||||
#endif
|
||||
|
||||
extern int call_rtas(const char *, int, int, unsigned long *, ...);
|
||||
|
|
|
@ -58,7 +58,7 @@ void do_rfi_flush_fixups(enum l1d_flush_type types);
|
|||
#ifdef CONFIG_PPC_BARRIER_NOSPEC
|
||||
void setup_barrier_nospec(void);
|
||||
#else
|
||||
static inline void setup_barrier_nospec(void) { };
|
||||
static inline void setup_barrier_nospec(void) { }
|
||||
#endif
|
||||
void do_uaccess_flush_fixups(enum l1d_flush_type types);
|
||||
void do_entry_flush_fixups(enum l1d_flush_type types);
|
||||
|
@ -68,13 +68,13 @@ extern bool barrier_nospec_enabled;
|
|||
#ifdef CONFIG_PPC_BARRIER_NOSPEC
|
||||
void do_barrier_nospec_fixups_range(bool enable, void *start, void *end);
|
||||
#else
|
||||
static inline void do_barrier_nospec_fixups_range(bool enable, void *start, void *end) { };
|
||||
static inline void do_barrier_nospec_fixups_range(bool enable, void *start, void *end) { }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PPC_FSL_BOOK3E
|
||||
void setup_spectre_v2(void);
|
||||
#else
|
||||
static inline void setup_spectre_v2(void) {};
|
||||
static inline void setup_spectre_v2(void) {}
|
||||
#endif
|
||||
void do_btb_flush_fixups(void);
|
||||
|
||||
|
|
|
@ -90,8 +90,8 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock)
|
|||
void splpar_spin_yield(arch_spinlock_t *lock);
|
||||
void splpar_rw_yield(arch_rwlock_t *lock);
|
||||
#else /* SPLPAR */
|
||||
static inline void splpar_spin_yield(arch_spinlock_t *lock) {};
|
||||
static inline void splpar_rw_yield(arch_rwlock_t *lock) {};
|
||||
static inline void splpar_spin_yield(arch_spinlock_t *lock) {}
|
||||
static inline void splpar_rw_yield(arch_rwlock_t *lock) {}
|
||||
#endif
|
||||
|
||||
static inline void spin_yield(arch_spinlock_t *lock)
|
||||
|
|
|
@ -236,7 +236,7 @@ static inline void set_hard_smp_processor_id(int cpu, int phys)
|
|||
#if defined(CONFIG_PPC64) && (defined(CONFIG_SMP) || defined(CONFIG_KEXEC_CORE))
|
||||
extern void smp_release_cpus(void);
|
||||
#else
|
||||
static inline void smp_release_cpus(void) { };
|
||||
static inline void smp_release_cpus(void) { }
|
||||
#endif
|
||||
|
||||
extern int smt_enabled_at_boot;
|
||||
|
|
|
@ -94,7 +94,6 @@ void arch_setup_new_exec(void);
|
|||
#define TIF_PATCH_PENDING 6 /* pending live patching update */
|
||||
#define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */
|
||||
#define TIF_SINGLESTEP 8 /* singlestepping active */
|
||||
#define TIF_NOHZ 9 /* in adaptive nohz mode */
|
||||
#define TIF_SECCOMP 10 /* secure computing */
|
||||
#define TIF_RESTOREALL 11 /* Restore all regs (implies NOERROR) */
|
||||
#define TIF_NOERROR 12 /* Force successful syscall return */
|
||||
|
@ -128,11 +127,10 @@ void arch_setup_new_exec(void);
|
|||
#define _TIF_UPROBE (1<<TIF_UPROBE)
|
||||
#define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT)
|
||||
#define _TIF_EMULATE_STACK_STORE (1<<TIF_EMULATE_STACK_STORE)
|
||||
#define _TIF_NOHZ (1<<TIF_NOHZ)
|
||||
#define _TIF_SYSCALL_EMU (1<<TIF_SYSCALL_EMU)
|
||||
#define _TIF_SYSCALL_DOTRACE (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
|
||||
_TIF_SECCOMP | _TIF_SYSCALL_TRACEPOINT | \
|
||||
_TIF_NOHZ | _TIF_SYSCALL_EMU)
|
||||
_TIF_SYSCALL_EMU)
|
||||
|
||||
#define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
|
||||
_TIF_NOTIFY_RESUME | _TIF_UPROBE | \
|
||||
|
|
|
@ -102,6 +102,8 @@ DECLARE_PER_CPU(u64, decrementers_next_tb);
|
|||
/* Convert timebase ticks to nanoseconds */
|
||||
unsigned long long tb_to_ns(unsigned long long tb_ticks);
|
||||
|
||||
void timer_broadcast_interrupt(void);
|
||||
|
||||
/* SPLPAR */
|
||||
void accumulate_stolen_time(void);
|
||||
|
||||
|
|
|
@ -52,8 +52,6 @@ static inline bool __access_ok(unsigned long addr, unsigned long size)
|
|||
__get_user_nocheck((x), (ptr), sizeof(*(ptr)), true)
|
||||
#define __put_user(x, ptr) \
|
||||
__put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
|
||||
#define __put_user_goto(x, ptr, label) \
|
||||
__put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
|
||||
|
||||
#define __get_user_allowed(x, ptr) \
|
||||
__get_user_nocheck((x), (ptr), sizeof(*(ptr)), false)
|
||||
|
@ -110,22 +108,18 @@ static inline bool __access_ok(unsigned long addr, unsigned long size)
|
|||
|
||||
extern long __put_user_bad(void);
|
||||
|
||||
#define __put_user_size_allowed(x, ptr, size, retval) \
|
||||
#define __put_user_size(x, ptr, size, retval) \
|
||||
do { \
|
||||
__label__ __pu_failed; \
|
||||
\
|
||||
retval = 0; \
|
||||
allow_write_to_user(ptr, size); \
|
||||
__put_user_size_goto(x, ptr, size, __pu_failed); \
|
||||
prevent_write_to_user(ptr, size); \
|
||||
break; \
|
||||
\
|
||||
__pu_failed: \
|
||||
retval = -EFAULT; \
|
||||
} while (0)
|
||||
|
||||
#define __put_user_size(x, ptr, size, retval) \
|
||||
do { \
|
||||
allow_write_to_user(ptr, size); \
|
||||
__put_user_size_allowed(x, ptr, size, retval); \
|
||||
prevent_write_to_user(ptr, size); \
|
||||
} while (0)
|
||||
|
||||
|
@ -213,11 +207,9 @@ do { \
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
#define __put_user_nocheck_goto(x, ptr, size, label) \
|
||||
#define __unsafe_put_user_goto(x, ptr, size, label) \
|
||||
do { \
|
||||
__typeof__(*(ptr)) __user *__pu_addr = (ptr); \
|
||||
if (!is_kernel_addr((unsigned long)__pu_addr)) \
|
||||
might_fault(); \
|
||||
__chk_user_ptr(ptr); \
|
||||
__put_user_size_goto((x), __pu_addr, (size), label); \
|
||||
} while (0)
|
||||
|
@ -313,9 +305,8 @@ do { \
|
|||
__typeof__(size) __gu_size = (size); \
|
||||
\
|
||||
__chk_user_ptr(__gu_addr); \
|
||||
if (!is_kernel_addr((unsigned long)__gu_addr)) \
|
||||
if (do_allow && !is_kernel_addr((unsigned long)__gu_addr)) \
|
||||
might_fault(); \
|
||||
barrier_nospec(); \
|
||||
if (do_allow) \
|
||||
__get_user_size(__gu_val, __gu_addr, __gu_size, __gu_err); \
|
||||
else \
|
||||
|
@ -333,10 +324,8 @@ do { \
|
|||
__typeof__(size) __gu_size = (size); \
|
||||
\
|
||||
might_fault(); \
|
||||
if (access_ok(__gu_addr, __gu_size)) { \
|
||||
barrier_nospec(); \
|
||||
if (access_ok(__gu_addr, __gu_size)) \
|
||||
__get_user_size(__gu_val, __gu_addr, __gu_size, __gu_err); \
|
||||
} \
|
||||
(x) = (__force __typeof__(*(ptr)))__gu_val; \
|
||||
\
|
||||
__gu_err; \
|
||||
|
@ -350,7 +339,6 @@ do { \
|
|||
__typeof__(size) __gu_size = (size); \
|
||||
\
|
||||
__chk_user_ptr(__gu_addr); \
|
||||
barrier_nospec(); \
|
||||
__get_user_size(__gu_val, __gu_addr, __gu_size, __gu_err); \
|
||||
(x) = (__force __typeof__(*(ptr)))__gu_val; \
|
||||
\
|
||||
|
@ -395,7 +383,6 @@ raw_copy_in_user(void __user *to, const void __user *from, unsigned long n)
|
|||
{
|
||||
unsigned long ret;
|
||||
|
||||
barrier_nospec();
|
||||
allow_read_write_user(to, from, n);
|
||||
ret = __copy_tofrom_user(to, from, n);
|
||||
prevent_read_write_user(to, from, n);
|
||||
|
@ -407,72 +394,20 @@ static inline unsigned long raw_copy_from_user(void *to,
|
|||
const void __user *from, unsigned long n)
|
||||
{
|
||||
unsigned long ret;
|
||||
if (__builtin_constant_p(n) && (n <= 8)) {
|
||||
ret = 1;
|
||||
|
||||
switch (n) {
|
||||
case 1:
|
||||
barrier_nospec();
|
||||
__get_user_size(*(u8 *)to, from, 1, ret);
|
||||
break;
|
||||
case 2:
|
||||
barrier_nospec();
|
||||
__get_user_size(*(u16 *)to, from, 2, ret);
|
||||
break;
|
||||
case 4:
|
||||
barrier_nospec();
|
||||
__get_user_size(*(u32 *)to, from, 4, ret);
|
||||
break;
|
||||
case 8:
|
||||
barrier_nospec();
|
||||
__get_user_size(*(u64 *)to, from, 8, ret);
|
||||
break;
|
||||
}
|
||||
if (ret == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
barrier_nospec();
|
||||
allow_read_from_user(from, n);
|
||||
ret = __copy_tofrom_user((__force void __user *)to, from, n);
|
||||
prevent_read_from_user(from, n);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
raw_copy_to_user_allowed(void __user *to, const void *from, unsigned long n)
|
||||
{
|
||||
if (__builtin_constant_p(n) && (n <= 8)) {
|
||||
unsigned long ret = 1;
|
||||
|
||||
switch (n) {
|
||||
case 1:
|
||||
__put_user_size_allowed(*(u8 *)from, (u8 __user *)to, 1, ret);
|
||||
break;
|
||||
case 2:
|
||||
__put_user_size_allowed(*(u16 *)from, (u16 __user *)to, 2, ret);
|
||||
break;
|
||||
case 4:
|
||||
__put_user_size_allowed(*(u32 *)from, (u32 __user *)to, 4, ret);
|
||||
break;
|
||||
case 8:
|
||||
__put_user_size_allowed(*(u64 *)from, (u64 __user *)to, 8, ret);
|
||||
break;
|
||||
}
|
||||
if (ret == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return __copy_tofrom_user(to, (__force const void __user *)from, n);
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
raw_copy_to_user(void __user *to, const void *from, unsigned long n)
|
||||
{
|
||||
unsigned long ret;
|
||||
|
||||
allow_write_to_user(to, n);
|
||||
ret = raw_copy_to_user_allowed(to, from, n);
|
||||
ret = __copy_tofrom_user(to, (__force const void __user *)from, n);
|
||||
prevent_write_to_user(to, n);
|
||||
return ret;
|
||||
}
|
||||
|
@ -508,6 +443,9 @@ static __must_check inline bool user_access_begin(const void __user *ptr, size_t
|
|||
{
|
||||
if (unlikely(!access_ok(ptr, len)))
|
||||
return false;
|
||||
|
||||
might_fault();
|
||||
|
||||
allow_read_write_user((void __user *)ptr, ptr, len);
|
||||
return true;
|
||||
}
|
||||
|
@ -521,6 +459,9 @@ user_read_access_begin(const void __user *ptr, size_t len)
|
|||
{
|
||||
if (unlikely(!access_ok(ptr, len)))
|
||||
return false;
|
||||
|
||||
might_fault();
|
||||
|
||||
allow_read_from_user(ptr, len);
|
||||
return true;
|
||||
}
|
||||
|
@ -532,6 +473,9 @@ user_write_access_begin(const void __user *ptr, size_t len)
|
|||
{
|
||||
if (unlikely(!access_ok(ptr, len)))
|
||||
return false;
|
||||
|
||||
might_fault();
|
||||
|
||||
allow_write_to_user((void __user *)ptr, len);
|
||||
return true;
|
||||
}
|
||||
|
@ -540,7 +484,8 @@ user_write_access_begin(const void __user *ptr, size_t len)
|
|||
|
||||
#define unsafe_op_wrap(op, err) do { if (unlikely(op)) goto err; } while (0)
|
||||
#define unsafe_get_user(x, p, e) unsafe_op_wrap(__get_user_allowed(x, p), e)
|
||||
#define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
|
||||
#define unsafe_put_user(x, p, e) \
|
||||
__unsafe_put_user_goto((__typeof__(*(p)))(x), (p), sizeof(*(p)), e)
|
||||
|
||||
#define unsafe_copy_to_user(d, s, l, e) \
|
||||
do { \
|
||||
|
@ -550,17 +495,17 @@ do { \
|
|||
int _i; \
|
||||
\
|
||||
for (_i = 0; _i < (_len & ~(sizeof(long) - 1)); _i += sizeof(long)) \
|
||||
__put_user_goto(*(long*)(_src + _i), (long __user *)(_dst + _i), e);\
|
||||
unsafe_put_user(*(long*)(_src + _i), (long __user *)(_dst + _i), e); \
|
||||
if (IS_ENABLED(CONFIG_PPC64) && (_len & 4)) { \
|
||||
__put_user_goto(*(u32*)(_src + _i), (u32 __user *)(_dst + _i), e); \
|
||||
unsafe_put_user(*(u32*)(_src + _i), (u32 __user *)(_dst + _i), e); \
|
||||
_i += 4; \
|
||||
} \
|
||||
if (_len & 2) { \
|
||||
__put_user_goto(*(u16*)(_src + _i), (u16 __user *)(_dst + _i), e); \
|
||||
unsafe_put_user(*(u16*)(_src + _i), (u16 __user *)(_dst + _i), e); \
|
||||
_i += 2; \
|
||||
} \
|
||||
if (_len & 1) \
|
||||
__put_user_goto(*(u8*)(_src + _i), (u8 __user *)(_dst + _i), e);\
|
||||
unsafe_put_user(*(u8*)(_src + _i), (u8 __user *)(_dst + _i), e); \
|
||||
} while (0)
|
||||
|
||||
#define HAVE_GET_KERNEL_NOFAULT
|
||||
|
|
|
@ -43,12 +43,6 @@
|
|||
#define mttbl(v) asm volatile("mttbl %0":: "r"(v))
|
||||
#define mttbu(v) asm volatile("mttbu %0":: "r"(v))
|
||||
|
||||
/* For compatibility, get_tbl() is defined as get_tb() on ppc64 */
|
||||
static inline unsigned long get_tbl(void)
|
||||
{
|
||||
return mftb();
|
||||
}
|
||||
|
||||
static __always_inline u64 get_tb(void)
|
||||
{
|
||||
unsigned int tbhi, tblo, tbhi2;
|
||||
|
|
|
@ -17,8 +17,8 @@ struct pt_regs;
|
|||
extern int xmon(struct pt_regs *excp);
|
||||
extern irqreturn_t xmon_irq(int, void *);
|
||||
#else
|
||||
static inline void xmon_setup(void) { };
|
||||
static inline void xmon_register_spus(struct list_head *list) { };
|
||||
static inline void xmon_setup(void) { }
|
||||
static inline void xmon_register_spus(struct list_head *list) { }
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_XMON) && defined(CONFIG_SMP)
|
||||
|
|
|
@ -55,17 +55,33 @@ enum perf_event_powerpc_regs {
|
|||
PERF_REG_POWERPC_MMCR3,
|
||||
PERF_REG_POWERPC_SIER2,
|
||||
PERF_REG_POWERPC_SIER3,
|
||||
PERF_REG_POWERPC_PMC1,
|
||||
PERF_REG_POWERPC_PMC2,
|
||||
PERF_REG_POWERPC_PMC3,
|
||||
PERF_REG_POWERPC_PMC4,
|
||||
PERF_REG_POWERPC_PMC5,
|
||||
PERF_REG_POWERPC_PMC6,
|
||||
/* Max regs without the extended regs */
|
||||
PERF_REG_POWERPC_MAX = PERF_REG_POWERPC_MMCRA + 1,
|
||||
};
|
||||
|
||||
#define PERF_REG_PMU_MASK ((1ULL << PERF_REG_POWERPC_MAX) - 1)
|
||||
|
||||
/* PERF_REG_EXTENDED_MASK value for CPU_FTR_ARCH_300 */
|
||||
#define PERF_REG_PMU_MASK_300 (((1ULL << (PERF_REG_POWERPC_MMCR2 + 1)) - 1) - PERF_REG_PMU_MASK)
|
||||
/* PERF_REG_EXTENDED_MASK value for CPU_FTR_ARCH_31 */
|
||||
#define PERF_REG_PMU_MASK_31 (((1ULL << (PERF_REG_POWERPC_SIER3 + 1)) - 1) - PERF_REG_PMU_MASK)
|
||||
/* Exclude MMCR3, SIER2, SIER3 for CPU_FTR_ARCH_300 */
|
||||
#define PERF_EXCLUDE_REG_EXT_300 (7ULL << PERF_REG_POWERPC_MMCR3)
|
||||
|
||||
#define PERF_REG_MAX_ISA_300 (PERF_REG_POWERPC_MMCR2 + 1)
|
||||
#define PERF_REG_MAX_ISA_31 (PERF_REG_POWERPC_SIER3 + 1)
|
||||
/*
|
||||
* PERF_REG_EXTENDED_MASK value for CPU_FTR_ARCH_300
|
||||
* includes 9 SPRS from MMCR0 to PMC6 excluding the
|
||||
* unsupported SPRS in PERF_EXCLUDE_REG_EXT_300.
|
||||
*/
|
||||
#define PERF_REG_PMU_MASK_300 ((0xfffULL << PERF_REG_POWERPC_MMCR0) - PERF_EXCLUDE_REG_EXT_300)
|
||||
|
||||
/*
|
||||
* PERF_REG_EXTENDED_MASK value for CPU_FTR_ARCH_31
|
||||
* includes 12 SPRs from MMCR0 to PMC6.
|
||||
*/
|
||||
#define PERF_REG_PMU_MASK_31 (0xfffULL << PERF_REG_POWERPC_MMCR0)
|
||||
|
||||
#define PERF_REG_EXTENDED_MAX (PERF_REG_POWERPC_PMC6 + 1)
|
||||
#endif /* _UAPI_ASM_POWERPC_PERF_REGS_H */
|
||||
|
|
|
@ -46,10 +46,10 @@ obj-y := cputable.o syscalls.o \
|
|||
prom.o traps.o setup-common.o \
|
||||
udbg.o misc.o io.o misc_$(BITS).o \
|
||||
of_platform.o prom_parse.o firmware.o \
|
||||
hw_breakpoint_constraints.o
|
||||
hw_breakpoint_constraints.o interrupt.o
|
||||
obj-y += ptrace/
|
||||
obj-$(CONFIG_PPC64) += setup_64.o \
|
||||
paca.o nvram_64.o note.o syscall_64.o
|
||||
paca.o nvram_64.o note.o
|
||||
obj-$(CONFIG_COMPAT) += sys_ppc32.o signal_32.o
|
||||
obj-$(CONFIG_VDSO32) += vdso32_wrapper.o
|
||||
obj-$(CONFIG_PPC_WATCHDOG) += watchdog.o
|
||||
|
|
|
@ -255,7 +255,6 @@ int main(void)
|
|||
#endif /* CONFIG_PPC_MM_SLICES */
|
||||
OFFSET(PACA_EXGEN, paca_struct, exgen);
|
||||
OFFSET(PACA_EXMC, paca_struct, exmc);
|
||||
OFFSET(PACA_EXSLB, paca_struct, exslb);
|
||||
OFFSET(PACA_EXNMI, paca_struct, exnmi);
|
||||
#ifdef CONFIG_PPC_PSERIES
|
||||
OFFSET(PACALPPACAPTR, paca_struct, lppaca_ptr);
|
||||
|
@ -309,7 +308,7 @@ int main(void)
|
|||
|
||||
/* Interrupt register frame */
|
||||
DEFINE(INT_FRAME_SIZE, STACK_INT_FRAME_SIZE);
|
||||
DEFINE(SWITCH_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs));
|
||||
DEFINE(SWITCH_FRAME_SIZE, STACK_FRAME_WITH_PT_REGS);
|
||||
STACK_PT_REGS_OFFSET(GPR0, gpr[0]);
|
||||
STACK_PT_REGS_OFFSET(GPR1, gpr[1]);
|
||||
STACK_PT_REGS_OFFSET(GPR2, gpr[2]);
|
||||
|
|
|
@ -12,17 +12,17 @@
|
|||
#include <linux/hardirq.h>
|
||||
|
||||
#include <asm/dbell.h>
|
||||
#include <asm/interrupt.h>
|
||||
#include <asm/irq_regs.h>
|
||||
#include <asm/kvm_ppc.h>
|
||||
#include <asm/trace.h>
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
void doorbell_exception(struct pt_regs *regs)
|
||||
DEFINE_INTERRUPT_HANDLER_ASYNC(doorbell_exception)
|
||||
{
|
||||
struct pt_regs *old_regs = set_irq_regs(regs);
|
||||
|
||||
irq_enter();
|
||||
trace_doorbell_entry(regs);
|
||||
|
||||
ppc_msgsync();
|
||||
|
@ -35,13 +35,12 @@ void doorbell_exception(struct pt_regs *regs)
|
|||
smp_ipi_demux_relaxed(); /* already performed the barrier */
|
||||
|
||||
trace_doorbell_exit(regs);
|
||||
irq_exit();
|
||||
|
||||
set_irq_regs(old_regs);
|
||||
}
|
||||
#else /* CONFIG_SMP */
|
||||
void doorbell_exception(struct pt_regs *regs)
|
||||
DEFINE_INTERRUPT_HANDLER_ASYNC(doorbell_exception)
|
||||
{
|
||||
printk(KERN_WARNING "Received doorbell on non-smp system\n");
|
||||
}
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
|
|
|
@ -1596,6 +1596,35 @@ static int proc_eeh_show(struct seq_file *m, void *v)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
|
||||
|
||||
static struct pci_dev *eeh_debug_lookup_pdev(struct file *filp,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
uint32_t domain, bus, dev, fn;
|
||||
struct pci_dev *pdev;
|
||||
char buf[20];
|
||||
int ret;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
ret = simple_write_to_buffer(buf, sizeof(buf)-1, ppos, user_buf, count);
|
||||
if (!ret)
|
||||
return ERR_PTR(-EFAULT);
|
||||
|
||||
ret = sscanf(buf, "%x:%x:%x.%x", &domain, &bus, &dev, &fn);
|
||||
if (ret != 4) {
|
||||
pr_err("%s: expected 4 args, got %d\n", __func__, ret);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
pdev = pci_get_domain_bus_and_slot(domain, bus, (dev << 3) | fn);
|
||||
if (!pdev)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
return pdev;
|
||||
}
|
||||
|
||||
static int eeh_enable_dbgfs_set(void *data, u64 val)
|
||||
{
|
||||
if (val)
|
||||
|
@ -1688,26 +1717,13 @@ static ssize_t eeh_dev_check_write(struct file *filp,
|
|||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
uint32_t domain, bus, dev, fn;
|
||||
struct pci_dev *pdev;
|
||||
struct eeh_dev *edev;
|
||||
char buf[20];
|
||||
int ret;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
ret = simple_write_to_buffer(buf, sizeof(buf)-1, ppos, user_buf, count);
|
||||
if (!ret)
|
||||
return -EFAULT;
|
||||
|
||||
ret = sscanf(buf, "%x:%x:%x.%x", &domain, &bus, &dev, &fn);
|
||||
if (ret != 4) {
|
||||
pr_err("%s: expected 4 args, got %d\n", __func__, ret);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pdev = pci_get_domain_bus_and_slot(domain, bus, (dev << 3) | fn);
|
||||
if (!pdev)
|
||||
return -ENODEV;
|
||||
pdev = eeh_debug_lookup_pdev(filp, user_buf, count, ppos);
|
||||
if (IS_ERR(pdev))
|
||||
return PTR_ERR(pdev);
|
||||
|
||||
edev = pci_dev_to_eeh_dev(pdev);
|
||||
if (!edev) {
|
||||
|
@ -1717,8 +1733,8 @@ static ssize_t eeh_dev_check_write(struct file *filp,
|
|||
}
|
||||
|
||||
ret = eeh_dev_check_failure(edev);
|
||||
pci_info(pdev, "eeh_dev_check_failure(%04x:%02x:%02x.%01x) = %d\n",
|
||||
domain, bus, dev, fn, ret);
|
||||
pci_info(pdev, "eeh_dev_check_failure(%s) = %d\n",
|
||||
pci_name(pdev), ret);
|
||||
|
||||
pci_dev_put(pdev);
|
||||
|
||||
|
@ -1829,25 +1845,12 @@ static ssize_t eeh_dev_break_write(struct file *filp,
|
|||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
uint32_t domain, bus, dev, fn;
|
||||
struct pci_dev *pdev;
|
||||
char buf[20];
|
||||
int ret;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
ret = simple_write_to_buffer(buf, sizeof(buf)-1, ppos, user_buf, count);
|
||||
if (!ret)
|
||||
return -EFAULT;
|
||||
|
||||
ret = sscanf(buf, "%x:%x:%x.%x", &domain, &bus, &dev, &fn);
|
||||
if (ret != 4) {
|
||||
pr_err("%s: expected 4 args, got %d\n", __func__, ret);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pdev = pci_get_domain_bus_and_slot(domain, bus, (dev << 3) | fn);
|
||||
if (!pdev)
|
||||
return -ENODEV;
|
||||
pdev = eeh_debug_lookup_pdev(filp, user_buf, count, ppos);
|
||||
if (IS_ERR(pdev))
|
||||
return PTR_ERR(pdev);
|
||||
|
||||
ret = eeh_debugfs_break_device(pdev);
|
||||
pci_dev_put(pdev);
|
||||
|
@ -1865,6 +1868,53 @@ static const struct file_operations eeh_dev_break_fops = {
|
|||
.read = eeh_debugfs_dev_usage,
|
||||
};
|
||||
|
||||
static ssize_t eeh_dev_can_recover(struct file *filp,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct pci_driver *drv;
|
||||
struct pci_dev *pdev;
|
||||
size_t ret;
|
||||
|
||||
pdev = eeh_debug_lookup_pdev(filp, user_buf, count, ppos);
|
||||
if (IS_ERR(pdev))
|
||||
return PTR_ERR(pdev);
|
||||
|
||||
/*
|
||||
* In order for error recovery to work the driver needs to implement
|
||||
* .error_detected(), so it can quiesce IO to the device, and
|
||||
* .slot_reset() so it can re-initialise the device after a reset.
|
||||
*
|
||||
* Ideally they'd implement .resume() too, but some drivers which
|
||||
* we need to support (notably IPR) don't so I guess we can tolerate
|
||||
* that.
|
||||
*
|
||||
* .mmio_enabled() is mostly there as a work-around for devices which
|
||||
* take forever to re-init after a hot reset. Implementing that is
|
||||
* strictly optional.
|
||||
*/
|
||||
drv = pci_dev_driver(pdev);
|
||||
if (drv &&
|
||||
drv->err_handler &&
|
||||
drv->err_handler->error_detected &&
|
||||
drv->err_handler->slot_reset) {
|
||||
ret = count;
|
||||
} else {
|
||||
ret = -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
pci_dev_put(pdev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct file_operations eeh_dev_can_recover_fops = {
|
||||
.open = simple_open,
|
||||
.llseek = no_llseek,
|
||||
.write = eeh_dev_can_recover,
|
||||
.read = eeh_debugfs_dev_usage,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
static int __init eeh_init_proc(void)
|
||||
|
@ -1889,6 +1939,9 @@ static int __init eeh_init_proc(void)
|
|||
debugfs_create_file_unsafe("eeh_force_recover", 0600,
|
||||
powerpc_debugfs_root, NULL,
|
||||
&eeh_force_recover_fops);
|
||||
debugfs_create_file_unsafe("eeh_dev_can_recover", 0600,
|
||||
powerpc_debugfs_root, NULL,
|
||||
&eeh_dev_can_recover_fops);
|
||||
eeh_cache_debugfs_init();
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -175,14 +175,11 @@ transfer_to_handler:
|
|||
addi r11,r11,global_dbcr0@l
|
||||
#ifdef CONFIG_SMP
|
||||
lwz r9,TASK_CPU(r2)
|
||||
slwi r9,r9,3
|
||||
slwi r9,r9,2
|
||||
add r11,r11,r9
|
||||
#endif
|
||||
lwz r12,0(r11)
|
||||
mtspr SPRN_DBCR0,r12
|
||||
lwz r12,4(r11)
|
||||
addi r12,r12,-1
|
||||
stw r12,4(r11)
|
||||
#endif
|
||||
|
||||
b 3f
|
||||
|
@ -276,8 +273,7 @@ reenable_mmu:
|
|||
* We save a bunch of GPRs,
|
||||
* r3 can be different from GPR3(r1) at this point, r9 and r11
|
||||
* contains the old MSR and handler address respectively,
|
||||
* r4 & r5 can contain page fault arguments that need to be passed
|
||||
* along as well. r0, r6-r8, r12, CCR, CTR, XER etc... are left
|
||||
* r0, r4-r8, r12, CCR, CTR, XER etc... are left
|
||||
* clobbered as they aren't useful past this point.
|
||||
*/
|
||||
|
||||
|
@ -285,15 +281,11 @@ reenable_mmu:
|
|||
stw r9,8(r1)
|
||||
stw r11,12(r1)
|
||||
stw r3,16(r1)
|
||||
stw r4,20(r1)
|
||||
stw r5,24(r1)
|
||||
|
||||
/* If we are disabling interrupts (normal case), simply log it with
|
||||
* lockdep
|
||||
*/
|
||||
1: bl trace_hardirqs_off
|
||||
lwz r5,24(r1)
|
||||
lwz r4,20(r1)
|
||||
lwz r3,16(r1)
|
||||
lwz r11,12(r1)
|
||||
lwz r9,8(r1)
|
||||
|
@ -334,132 +326,29 @@ stack_ovf:
|
|||
_ASM_NOKPROBE_SYMBOL(stack_ovf)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
trace_syscall_entry_irq_off:
|
||||
/*
|
||||
* Syscall shouldn't happen while interrupts are disabled,
|
||||
* so let's do a warning here.
|
||||
*/
|
||||
0: trap
|
||||
EMIT_BUG_ENTRY 0b,__FILE__,__LINE__, BUGFLAG_WARNING
|
||||
bl trace_hardirqs_on
|
||||
|
||||
/* Now enable for real */
|
||||
LOAD_REG_IMMEDIATE(r10, MSR_KERNEL | MSR_EE)
|
||||
mtmsr r10
|
||||
|
||||
REST_GPR(0, r1)
|
||||
REST_4GPRS(3, r1)
|
||||
REST_2GPRS(7, r1)
|
||||
b DoSyscall
|
||||
#endif /* CONFIG_TRACE_IRQFLAGS */
|
||||
|
||||
.globl transfer_to_syscall
|
||||
transfer_to_syscall:
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
andi. r12,r9,MSR_EE
|
||||
beq- trace_syscall_entry_irq_off
|
||||
#endif /* CONFIG_TRACE_IRQFLAGS */
|
||||
SAVE_NVGPRS(r1)
|
||||
#ifdef CONFIG_PPC_BOOK3S_32
|
||||
kuep_lock r11, r12
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Handle a system call.
|
||||
*/
|
||||
.stabs "arch/powerpc/kernel/",N_SO,0,0,0f
|
||||
.stabs "entry_32.S",N_SO,0,0,0f
|
||||
0:
|
||||
/* Calling convention has r9 = orig r0, r10 = regs */
|
||||
addi r10,r1,STACK_FRAME_OVERHEAD
|
||||
mr r9,r0
|
||||
stw r10,THREAD+PT_REGS(r2)
|
||||
bl system_call_exception
|
||||
|
||||
_GLOBAL(DoSyscall)
|
||||
stw r3,ORIG_GPR3(r1)
|
||||
li r12,0
|
||||
stw r12,RESULT(r1)
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
/* Make sure interrupts are enabled */
|
||||
mfmsr r11
|
||||
andi. r12,r11,MSR_EE
|
||||
/* We came in with interrupts disabled, we WARN and mark them enabled
|
||||
* for lockdep now */
|
||||
0: tweqi r12, 0
|
||||
EMIT_BUG_ENTRY 0b,__FILE__,__LINE__, BUGFLAG_WARNING
|
||||
#endif /* CONFIG_TRACE_IRQFLAGS */
|
||||
lwz r11,TI_FLAGS(r2)
|
||||
andi. r11,r11,_TIF_SYSCALL_DOTRACE
|
||||
bne- syscall_dotrace
|
||||
syscall_dotrace_cont:
|
||||
cmplwi 0,r0,NR_syscalls
|
||||
lis r10,sys_call_table@h
|
||||
ori r10,r10,sys_call_table@l
|
||||
slwi r0,r0,2
|
||||
bge- 66f
|
||||
|
||||
barrier_nospec_asm
|
||||
/*
|
||||
* Prevent the load of the handler below (based on the user-passed
|
||||
* system call number) being speculatively executed until the test
|
||||
* against NR_syscalls and branch to .66f above has
|
||||
* committed.
|
||||
*/
|
||||
|
||||
lwzx r10,r10,r0 /* Fetch system call handler [ptr] */
|
||||
mtlr r10
|
||||
addi r9,r1,STACK_FRAME_OVERHEAD
|
||||
PPC440EP_ERR42
|
||||
blrl /* Call handler */
|
||||
.globl ret_from_syscall
|
||||
ret_from_syscall:
|
||||
#ifdef CONFIG_DEBUG_RSEQ
|
||||
/* Check whether the syscall is issued inside a restartable sequence */
|
||||
stw r3,GPR3(r1)
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl rseq_syscall
|
||||
lwz r3,GPR3(r1)
|
||||
#endif
|
||||
mr r6,r3
|
||||
/* disable interrupts so current_thread_info()->flags can't change */
|
||||
LOAD_REG_IMMEDIATE(r10,MSR_KERNEL) /* doesn't include MSR_EE */
|
||||
/* Note: We don't bother telling lockdep about it */
|
||||
mtmsr r10
|
||||
lwz r9,TI_FLAGS(r2)
|
||||
li r8,-MAX_ERRNO
|
||||
andi. r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK)
|
||||
bne- syscall_exit_work
|
||||
cmplw 0,r3,r8
|
||||
blt+ syscall_exit_cont
|
||||
lwz r11,_CCR(r1) /* Load CR */
|
||||
neg r3,r3
|
||||
oris r11,r11,0x1000 /* Set SO bit in CR */
|
||||
stw r11,_CCR(r1)
|
||||
syscall_exit_cont:
|
||||
lwz r8,_MSR(r1)
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
/* If we are going to return from the syscall with interrupts
|
||||
* off, we trace that here. It shouldn't normally happen.
|
||||
*/
|
||||
andi. r10,r8,MSR_EE
|
||||
bne+ 1f
|
||||
stw r3,GPR3(r1)
|
||||
bl trace_hardirqs_off
|
||||
lwz r3,GPR3(r1)
|
||||
1:
|
||||
#endif /* CONFIG_TRACE_IRQFLAGS */
|
||||
#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
|
||||
/* If the process has its own DBCR0 value, load it up. The internal
|
||||
debug mode bit tells us that dbcr0 should be loaded. */
|
||||
lwz r0,THREAD+THREAD_DBCR0(r2)
|
||||
andis. r10,r0,DBCR0_IDM@h
|
||||
bnel- load_dbcr0
|
||||
#endif
|
||||
addi r4,r1,STACK_FRAME_OVERHEAD
|
||||
li r5,0
|
||||
bl syscall_exit_prepare
|
||||
#ifdef CONFIG_PPC_47x
|
||||
lis r4,icache_44x_need_flush@ha
|
||||
lwz r5,icache_44x_need_flush@l(r4)
|
||||
cmplwi cr0,r5,0
|
||||
bne- 2f
|
||||
#endif /* CONFIG_PPC_47x */
|
||||
1:
|
||||
BEGIN_FTR_SECTION
|
||||
lwarx r7,0,r1
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
|
||||
stwcx. r0,0,r1 /* to clear the reservation */
|
||||
ACCOUNT_CPU_USER_EXIT(r2, r5, r7)
|
||||
#ifdef CONFIG_PPC_BOOK3S_32
|
||||
kuep_unlock r5, r7
|
||||
#endif
|
||||
|
@ -467,21 +356,36 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
|
|||
lwz r4,_LINK(r1)
|
||||
lwz r5,_CCR(r1)
|
||||
mtlr r4
|
||||
mtcr r5
|
||||
lwz r7,_NIP(r1)
|
||||
lwz r2,GPR2(r1)
|
||||
lwz r1,GPR1(r1)
|
||||
lwz r8,_MSR(r1)
|
||||
cmpwi r3,0
|
||||
lwz r3,GPR3(r1)
|
||||
syscall_exit_finish:
|
||||
#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PERF_EVENTS)
|
||||
mtspr SPRN_NRI, r0
|
||||
#endif
|
||||
mtspr SPRN_SRR0,r7
|
||||
mtspr SPRN_SRR1,r8
|
||||
|
||||
bne 3f
|
||||
mtcr r5
|
||||
|
||||
1: lwz r2,GPR2(r1)
|
||||
lwz r1,GPR1(r1)
|
||||
rfi
|
||||
#ifdef CONFIG_40x
|
||||
b . /* Prevent prefetch past rfi */
|
||||
#endif
|
||||
_ASM_NOKPROBE_SYMBOL(syscall_exit_finish)
|
||||
|
||||
3: mtcr r5
|
||||
lwz r4,_CTR(r1)
|
||||
lwz r5,_XER(r1)
|
||||
REST_NVGPRS(r1)
|
||||
mtctr r4
|
||||
mtxer r5
|
||||
lwz r0,GPR0(r1)
|
||||
lwz r3,GPR3(r1)
|
||||
REST_8GPRS(4,r1)
|
||||
lwz r12,GPR12(r1)
|
||||
b 1b
|
||||
|
||||
#ifdef CONFIG_44x
|
||||
2: li r7,0
|
||||
iccci r0,r0
|
||||
|
@ -489,9 +393,6 @@ _ASM_NOKPROBE_SYMBOL(syscall_exit_finish)
|
|||
b 1b
|
||||
#endif /* CONFIG_44x */
|
||||
|
||||
66: li r3,-ENOSYS
|
||||
b ret_from_syscall
|
||||
|
||||
.globl ret_from_fork
|
||||
ret_from_fork:
|
||||
REST_NVGPRS(r1)
|
||||
|
@ -510,157 +411,6 @@ ret_from_kernel_thread:
|
|||
li r3,0
|
||||
b ret_from_syscall
|
||||
|
||||
/* Traced system call support */
|
||||
syscall_dotrace:
|
||||
SAVE_NVGPRS(r1)
|
||||
li r0,0xc00
|
||||
stw r0,_TRAP(r1)
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl do_syscall_trace_enter
|
||||
/*
|
||||
* Restore argument registers possibly just changed.
|
||||
* We use the return value of do_syscall_trace_enter
|
||||
* for call number to look up in the table (r0).
|
||||
*/
|
||||
mr r0,r3
|
||||
lwz r3,GPR3(r1)
|
||||
lwz r4,GPR4(r1)
|
||||
lwz r5,GPR5(r1)
|
||||
lwz r6,GPR6(r1)
|
||||
lwz r7,GPR7(r1)
|
||||
lwz r8,GPR8(r1)
|
||||
REST_NVGPRS(r1)
|
||||
|
||||
cmplwi r0,NR_syscalls
|
||||
/* Return code is already in r3 thanks to do_syscall_trace_enter() */
|
||||
bge- ret_from_syscall
|
||||
b syscall_dotrace_cont
|
||||
|
||||
syscall_exit_work:
|
||||
andi. r0,r9,_TIF_RESTOREALL
|
||||
beq+ 0f
|
||||
REST_NVGPRS(r1)
|
||||
b 2f
|
||||
0: cmplw 0,r3,r8
|
||||
blt+ 1f
|
||||
andi. r0,r9,_TIF_NOERROR
|
||||
bne- 1f
|
||||
lwz r11,_CCR(r1) /* Load CR */
|
||||
neg r3,r3
|
||||
oris r11,r11,0x1000 /* Set SO bit in CR */
|
||||
stw r11,_CCR(r1)
|
||||
|
||||
1: stw r6,RESULT(r1) /* Save result */
|
||||
stw r3,GPR3(r1) /* Update return value */
|
||||
2: andi. r0,r9,(_TIF_PERSYSCALL_MASK)
|
||||
beq 4f
|
||||
|
||||
/* Clear per-syscall TIF flags if any are set. */
|
||||
|
||||
li r11,_TIF_PERSYSCALL_MASK
|
||||
addi r12,r2,TI_FLAGS
|
||||
3: lwarx r8,0,r12
|
||||
andc r8,r8,r11
|
||||
stwcx. r8,0,r12
|
||||
bne- 3b
|
||||
|
||||
4: /* Anything which requires enabling interrupts? */
|
||||
andi. r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP)
|
||||
beq ret_from_except
|
||||
|
||||
/* Re-enable interrupts. There is no need to trace that with
|
||||
* lockdep as we are supposed to have IRQs on at this point
|
||||
*/
|
||||
ori r10,r10,MSR_EE
|
||||
mtmsr r10
|
||||
|
||||
/* Save NVGPRS if they're not saved already */
|
||||
lwz r4,_TRAP(r1)
|
||||
andi. r4,r4,1
|
||||
beq 5f
|
||||
SAVE_NVGPRS(r1)
|
||||
li r4,0xc00
|
||||
stw r4,_TRAP(r1)
|
||||
5:
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl do_syscall_trace_leave
|
||||
b ret_from_except_full
|
||||
|
||||
/*
|
||||
* System call was called from kernel. We get here with SRR1 in r9.
|
||||
* Mark the exception as recoverable once we have retrieved SRR0,
|
||||
* trap a warning and return ENOSYS with CR[SO] set.
|
||||
*/
|
||||
.globl ret_from_kernel_syscall
|
||||
ret_from_kernel_syscall:
|
||||
mfspr r9, SPRN_SRR0
|
||||
mfspr r10, SPRN_SRR1
|
||||
#if !defined(CONFIG_4xx) && !defined(CONFIG_BOOKE)
|
||||
LOAD_REG_IMMEDIATE(r11, MSR_KERNEL & ~(MSR_IR|MSR_DR))
|
||||
mtmsr r11
|
||||
#endif
|
||||
|
||||
0: trap
|
||||
EMIT_BUG_ENTRY 0b,__FILE__,__LINE__, BUGFLAG_WARNING
|
||||
|
||||
li r3, ENOSYS
|
||||
crset so
|
||||
#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PERF_EVENTS)
|
||||
mtspr SPRN_NRI, r0
|
||||
#endif
|
||||
mtspr SPRN_SRR0, r9
|
||||
mtspr SPRN_SRR1, r10
|
||||
rfi
|
||||
#ifdef CONFIG_40x
|
||||
b . /* Prevent prefetch past rfi */
|
||||
#endif
|
||||
_ASM_NOKPROBE_SYMBOL(ret_from_kernel_syscall)
|
||||
|
||||
/*
|
||||
* The fork/clone functions need to copy the full register set into
|
||||
* the child process. Therefore we need to save all the nonvolatile
|
||||
* registers (r13 - r31) before calling the C code.
|
||||
*/
|
||||
.globl ppc_fork
|
||||
ppc_fork:
|
||||
SAVE_NVGPRS(r1)
|
||||
lwz r0,_TRAP(r1)
|
||||
rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
|
||||
stw r0,_TRAP(r1) /* register set saved */
|
||||
b sys_fork
|
||||
|
||||
.globl ppc_vfork
|
||||
ppc_vfork:
|
||||
SAVE_NVGPRS(r1)
|
||||
lwz r0,_TRAP(r1)
|
||||
rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
|
||||
stw r0,_TRAP(r1) /* register set saved */
|
||||
b sys_vfork
|
||||
|
||||
.globl ppc_clone
|
||||
ppc_clone:
|
||||
SAVE_NVGPRS(r1)
|
||||
lwz r0,_TRAP(r1)
|
||||
rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
|
||||
stw r0,_TRAP(r1) /* register set saved */
|
||||
b sys_clone
|
||||
|
||||
.globl ppc_clone3
|
||||
ppc_clone3:
|
||||
SAVE_NVGPRS(r1)
|
||||
lwz r0,_TRAP(r1)
|
||||
rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
|
||||
stw r0,_TRAP(r1) /* register set saved */
|
||||
b sys_clone3
|
||||
|
||||
.globl ppc_swapcontext
|
||||
ppc_swapcontext:
|
||||
SAVE_NVGPRS(r1)
|
||||
lwz r0,_TRAP(r1)
|
||||
rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
|
||||
stw r0,_TRAP(r1) /* register set saved */
|
||||
b sys_swapcontext
|
||||
|
||||
/*
|
||||
* Top-level page fault handling.
|
||||
* This is in assembler because if do_page_fault tells us that
|
||||
|
@ -670,10 +420,6 @@ ppc_swapcontext:
|
|||
.globl handle_page_fault
|
||||
handle_page_fault:
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
#ifdef CONFIG_PPC_BOOK3S_32
|
||||
andis. r0,r5,DSISR_DABRMATCH@h
|
||||
bne- handle_dabr_fault
|
||||
#endif
|
||||
bl do_page_fault
|
||||
cmpwi r3,0
|
||||
beq+ ret_from_except
|
||||
|
@ -681,23 +427,11 @@ handle_page_fault:
|
|||
lwz r0,_TRAP(r1)
|
||||
clrrwi r0,r0,1
|
||||
stw r0,_TRAP(r1)
|
||||
mr r5,r3
|
||||
mr r4,r3 /* err arg for bad_page_fault */
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
lwz r4,_DAR(r1)
|
||||
bl __bad_page_fault
|
||||
b ret_from_except_full
|
||||
|
||||
#ifdef CONFIG_PPC_BOOK3S_32
|
||||
/* We have a data breakpoint exception - handle it */
|
||||
handle_dabr_fault:
|
||||
SAVE_NVGPRS(r1)
|
||||
lwz r0,_TRAP(r1)
|
||||
clrrwi r0,r0,1
|
||||
stw r0,_TRAP(r1)
|
||||
bl do_break
|
||||
b ret_from_except_full
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This routine switches between two different tasks. The process
|
||||
* state of one is saved on its kernel stack. Then the state
|
||||
|
@ -1237,14 +971,11 @@ load_dbcr0:
|
|||
addi r11,r11,global_dbcr0@l
|
||||
#ifdef CONFIG_SMP
|
||||
lwz r9,TASK_CPU(r2)
|
||||
slwi r9,r9,3
|
||||
slwi r9,r9,2
|
||||
add r11,r11,r9
|
||||
#endif
|
||||
stw r10,0(r11)
|
||||
mtspr SPRN_DBCR0,r0
|
||||
lwz r10,4(r11)
|
||||
addi r10,r10,1
|
||||
stw r10,4(r11)
|
||||
li r11,-1
|
||||
mtspr SPRN_DBSR,r11 /* clear all pending debug events */
|
||||
blr
|
||||
|
@ -1253,7 +984,7 @@ load_dbcr0:
|
|||
.align 4
|
||||
.global global_dbcr0
|
||||
global_dbcr0:
|
||||
.space 8*NR_CPUS
|
||||
.space 4*NR_CPUS
|
||||
.previous
|
||||
#endif /* !(CONFIG_4xx || CONFIG_BOOKE) */
|
||||
|
||||
|
|
|
@ -108,7 +108,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM)
|
|||
li r11,\trapnr
|
||||
std r11,_TRAP(r1)
|
||||
std r12,_CCR(r1)
|
||||
std r3,ORIG_GPR3(r1)
|
||||
addi r10,r1,STACK_FRAME_OVERHEAD
|
||||
ld r11,exception_marker@toc(r2)
|
||||
std r11,-16(r10) /* "regshere" marker */
|
||||
|
@ -225,6 +224,12 @@ _ASM_NOKPROBE_SYMBOL(system_call_vectored_emulate)
|
|||
b system_call_vectored_common
|
||||
#endif
|
||||
|
||||
.balign IFETCH_ALIGN_BYTES
|
||||
.globl system_call_common_real
|
||||
system_call_common_real:
|
||||
ld r10,PACAKMSR(r13) /* get MSR value for kernel */
|
||||
mtmsrd r10
|
||||
|
||||
.balign IFETCH_ALIGN_BYTES
|
||||
.globl system_call_common
|
||||
system_call_common:
|
||||
|
@ -278,7 +283,6 @@ END_BTB_FLUSH_SECTION
|
|||
std r10,_LINK(r1)
|
||||
std r11,_TRAP(r1)
|
||||
std r12,_CCR(r1)
|
||||
std r3,ORIG_GPR3(r1)
|
||||
addi r10,r1,STACK_FRAME_OVERHEAD
|
||||
ld r11,exception_marker@toc(r2)
|
||||
std r11,-16(r10) /* "regshere" marker */
|
||||
|
|
|
@ -398,7 +398,6 @@ exc_##n##_common: \
|
|||
std r10,_NIP(r1); /* save SRR0 to stackframe */ \
|
||||
std r11,_MSR(r1); /* save SRR1 to stackframe */ \
|
||||
beq 2f; /* if from kernel mode */ \
|
||||
ACCOUNT_CPU_USER_ENTRY(r13,r10,r11);/* accounting (uses cr0+eq) */ \
|
||||
2: ld r3,excf+EX_R10(r13); /* get back r10 */ \
|
||||
ld r4,excf+EX_R11(r13); /* get back r11 */ \
|
||||
mfspr r5,scratch; /* get back r13 */ \
|
||||
|
@ -791,7 +790,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
|
|||
EXCEPTION_COMMON_CRIT(0xd00)
|
||||
std r14,_DSISR(r1)
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
mr r4,r14
|
||||
ld r14,PACA_EXCRIT+EX_R14(r13)
|
||||
ld r15,PACA_EXCRIT+EX_R15(r13)
|
||||
bl save_nvgprs
|
||||
|
@ -864,7 +862,6 @@ kernel_dbg_exc:
|
|||
INTS_DISABLE
|
||||
std r14,_DSISR(r1)
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
mr r4,r14
|
||||
ld r14,PACA_EXDBG+EX_R14(r13)
|
||||
ld r15,PACA_EXDBG+EX_R15(r13)
|
||||
bl save_nvgprs
|
||||
|
@ -1011,8 +1008,6 @@ storage_fault_common:
|
|||
std r14,_DAR(r1)
|
||||
std r15,_DSISR(r1)
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
mr r4,r14
|
||||
mr r5,r15
|
||||
ld r14,PACA_EXGEN+EX_R14(r13)
|
||||
ld r15,PACA_EXGEN+EX_R15(r13)
|
||||
bl do_page_fault
|
||||
|
@ -1020,9 +1015,8 @@ storage_fault_common:
|
|||
bne- 1f
|
||||
b ret_from_except_lite
|
||||
1: bl save_nvgprs
|
||||
mr r5,r3
|
||||
mr r4,r3
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
ld r4,_DAR(r1)
|
||||
bl __bad_page_fault
|
||||
b ret_from_except
|
||||
|
||||
|
|
|
@ -139,7 +139,6 @@ name:
|
|||
#define IKVM_VIRT .L_IKVM_VIRT_\name\() /* Virt entry tests KVM */
|
||||
#define ISTACK .L_ISTACK_\name\() /* Set regular kernel stack */
|
||||
#define __ISTACK(name) .L_ISTACK_ ## name
|
||||
#define IRECONCILE .L_IRECONCILE_\name\() /* Do RECONCILE_IRQ_STATE */
|
||||
#define IKUAP .L_IKUAP_\name\() /* Do KUAP lock */
|
||||
|
||||
#define INT_DEFINE_BEGIN(n) \
|
||||
|
@ -203,9 +202,6 @@ do_define_int n
|
|||
.ifndef ISTACK
|
||||
ISTACK=1
|
||||
.endif
|
||||
.ifndef IRECONCILE
|
||||
IRECONCILE=1
|
||||
.endif
|
||||
.ifndef IKUAP
|
||||
IKUAP=1
|
||||
.endif
|
||||
|
@ -581,7 +577,6 @@ DEFINE_FIXED_SYMBOL(\name\()_common_real)
|
|||
kuap_save_amr_and_lock r9, r10, cr1, cr0
|
||||
.endif
|
||||
beq 101f /* if from kernel mode */
|
||||
ACCOUNT_CPU_USER_ENTRY(r13, r9, r10)
|
||||
BEGIN_FTR_SECTION
|
||||
ld r9,IAREA+EX_PPR(r13) /* Read PPR from paca */
|
||||
std r9,_PPR(r1)
|
||||
|
@ -649,14 +644,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
|
|||
ld r11,exception_marker@toc(r2)
|
||||
std r10,RESULT(r1) /* clear regs->result */
|
||||
std r11,STACK_FRAME_OVERHEAD-16(r1) /* mark the frame */
|
||||
|
||||
.if ISTACK
|
||||
ACCOUNT_STOLEN_TIME
|
||||
.endif
|
||||
|
||||
.if IRECONCILE
|
||||
RECONCILE_IRQ_STATE(r10, r11)
|
||||
.endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
|
@ -705,14 +692,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
|
|||
ld r1,GPR1(r1)
|
||||
.endm
|
||||
|
||||
#define RUNLATCH_ON \
|
||||
BEGIN_FTR_SECTION \
|
||||
ld r3, PACA_THREAD_INFO(r13); \
|
||||
ld r4,TI_LOCAL_FLAGS(r3); \
|
||||
andi. r0,r4,_TLF_RUNLATCH; \
|
||||
beql ppc64_runlatch_on_trampoline; \
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_CTRL)
|
||||
|
||||
/*
|
||||
* When the idle code in power4_idle puts the CPU into NAP mode,
|
||||
* it has to do so in a loop, and relies on the external interrupt
|
||||
|
@ -935,7 +914,6 @@ INT_DEFINE_BEGIN(system_reset)
|
|||
*/
|
||||
ISET_RI=0
|
||||
ISTACK=0
|
||||
IRECONCILE=0
|
||||
IKVM_REAL=1
|
||||
INT_DEFINE_END(system_reset)
|
||||
|
||||
|
@ -1022,20 +1000,6 @@ EXC_COMMON_BEGIN(system_reset_common)
|
|||
ld r1,PACA_NMI_EMERG_SP(r13)
|
||||
subi r1,r1,INT_FRAME_SIZE
|
||||
__GEN_COMMON_BODY system_reset
|
||||
/*
|
||||
* Set IRQS_ALL_DISABLED unconditionally so irqs_disabled() does
|
||||
* the right thing. We do not want to reconcile because that goes
|
||||
* through irq tracing which we don't want in NMI.
|
||||
*
|
||||
* Save PACAIRQHAPPENED to RESULT (otherwise unused), and set HARD_DIS
|
||||
* as we are running with MSR[EE]=0.
|
||||
*/
|
||||
li r10,IRQS_ALL_DISABLED
|
||||
stb r10,PACAIRQSOFTMASK(r13)
|
||||
lbz r10,PACAIRQHAPPENED(r13)
|
||||
std r10,RESULT(r1)
|
||||
ori r10,r10,PACA_IRQ_HARD_DIS
|
||||
stb r10,PACAIRQHAPPENED(r13)
|
||||
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl system_reset_exception
|
||||
|
@ -1051,14 +1015,6 @@ EXC_COMMON_BEGIN(system_reset_common)
|
|||
subi r10,r10,1
|
||||
sth r10,PACA_IN_NMI(r13)
|
||||
|
||||
/*
|
||||
* Restore soft mask settings.
|
||||
*/
|
||||
ld r10,RESULT(r1)
|
||||
stb r10,PACAIRQHAPPENED(r13)
|
||||
ld r10,SOFTE(r1)
|
||||
stb r10,PACAIRQSOFTMASK(r13)
|
||||
|
||||
kuap_kernel_restore r9, r10
|
||||
EXCEPTION_RESTORE_REGS
|
||||
RFI_TO_USER_OR_KERNEL
|
||||
|
@ -1123,7 +1079,6 @@ INT_DEFINE_BEGIN(machine_check_early)
|
|||
ISTACK=0
|
||||
IDAR=1
|
||||
IDSISR=1
|
||||
IRECONCILE=0
|
||||
IKUAP=0 /* We don't touch AMR here, we never go to virtual mode */
|
||||
INT_DEFINE_END(machine_check_early)
|
||||
|
||||
|
@ -1205,30 +1160,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
|
|||
li r10,MSR_RI
|
||||
mtmsrd r10,1
|
||||
|
||||
/*
|
||||
* Set IRQS_ALL_DISABLED and save PACAIRQHAPPENED (see
|
||||
* system_reset_common)
|
||||
*/
|
||||
li r10,IRQS_ALL_DISABLED
|
||||
stb r10,PACAIRQSOFTMASK(r13)
|
||||
lbz r10,PACAIRQHAPPENED(r13)
|
||||
std r10,RESULT(r1)
|
||||
ori r10,r10,PACA_IRQ_HARD_DIS
|
||||
stb r10,PACAIRQHAPPENED(r13)
|
||||
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl machine_check_early
|
||||
std r3,RESULT(r1) /* Save result */
|
||||
ld r12,_MSR(r1)
|
||||
|
||||
/*
|
||||
* Restore soft mask settings.
|
||||
*/
|
||||
ld r10,RESULT(r1)
|
||||
stb r10,PACAIRQHAPPENED(r13)
|
||||
ld r10,SOFTE(r1)
|
||||
stb r10,PACAIRQSOFTMASK(r13)
|
||||
|
||||
#ifdef CONFIG_PPC_P7_NAP
|
||||
/*
|
||||
* Check if thread was in power saving mode. We come here when any
|
||||
|
@ -1401,14 +1337,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
|
|||
*
|
||||
* Handling:
|
||||
* - Hash MMU
|
||||
* Go to do_hash_page first to see if the HPT can be filled from an entry in
|
||||
* the Linux page table. Hash faults can hit in kernel mode in a fairly
|
||||
* Go to do_hash_fault, which attempts to fill the HPT from an entry in the
|
||||
* Linux page table. Hash faults can hit in kernel mode in a fairly
|
||||
* arbitrary state (e.g., interrupts disabled, locks held) when accessing
|
||||
* "non-bolted" regions, e.g., vmalloc space. However these should always be
|
||||
* backed by Linux page tables.
|
||||
* backed by Linux page table entries.
|
||||
*
|
||||
* If none is found, do a Linux page fault. Linux page faults can happen in
|
||||
* kernel mode due to user copy operations of course.
|
||||
* If no entry is found the Linux page fault handler is invoked (by
|
||||
* do_hash_fault). Linux page faults can happen in kernel mode due to user
|
||||
* copy operations of course.
|
||||
*
|
||||
* KVM: The KVM HDSI handler may perform a load with MSR[DR]=1 in guest
|
||||
* MMU context, which may cause a DSI in the host, which must go to the
|
||||
|
@ -1437,15 +1374,24 @@ EXC_VIRT_BEGIN(data_access, 0x4300, 0x80)
|
|||
EXC_VIRT_END(data_access, 0x4300, 0x80)
|
||||
EXC_COMMON_BEGIN(data_access_common)
|
||||
GEN_COMMON data_access
|
||||
ld r4,_DAR(r1)
|
||||
ld r5,_DSISR(r1)
|
||||
ld r4,_DSISR(r1)
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
andis. r0,r4,DSISR_DABRMATCH@h
|
||||
bne- 1f
|
||||
BEGIN_MMU_FTR_SECTION
|
||||
ld r6,_MSR(r1)
|
||||
li r3,0x300
|
||||
b do_hash_page /* Try to handle as hpte fault */
|
||||
bl do_hash_fault
|
||||
MMU_FTR_SECTION_ELSE
|
||||
b handle_page_fault
|
||||
bl do_page_fault
|
||||
ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX)
|
||||
b interrupt_return
|
||||
|
||||
1: bl do_break
|
||||
/*
|
||||
* do_break() may have changed the NV GPRS while handling a breakpoint.
|
||||
* If so, we need to restore them with their updated values.
|
||||
*/
|
||||
REST_NVGPRS(r1)
|
||||
b interrupt_return
|
||||
|
||||
GEN_KVM data_access
|
||||
|
||||
|
@ -1466,14 +1412,9 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX)
|
|||
* on user-handler data structures.
|
||||
*
|
||||
* KVM: Same as 0x300, DSLB must test for KVM guest.
|
||||
*
|
||||
* A dedicated save area EXSLB is used (XXX: but it actually need not be
|
||||
* these days, we could use EXGEN).
|
||||
*/
|
||||
INT_DEFINE_BEGIN(data_access_slb)
|
||||
IVEC=0x380
|
||||
IAREA=PACA_EXSLB
|
||||
IRECONCILE=0
|
||||
IDAR=1
|
||||
IKVM_SKIP=1
|
||||
IKVM_REAL=1
|
||||
|
@ -1487,10 +1428,9 @@ EXC_VIRT_BEGIN(data_access_slb, 0x4380, 0x80)
|
|||
EXC_VIRT_END(data_access_slb, 0x4380, 0x80)
|
||||
EXC_COMMON_BEGIN(data_access_slb_common)
|
||||
GEN_COMMON data_access_slb
|
||||
ld r4,_DAR(r1)
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
BEGIN_MMU_FTR_SECTION
|
||||
/* HPT case, do SLB fault */
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl do_slb_fault
|
||||
cmpdi r3,0
|
||||
bne- 1f
|
||||
|
@ -1501,9 +1441,6 @@ MMU_FTR_SECTION_ELSE
|
|||
li r3,-EFAULT
|
||||
ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX)
|
||||
std r3,RESULT(r1)
|
||||
RECONCILE_IRQ_STATE(r10, r11)
|
||||
ld r4,_DAR(r1)
|
||||
ld r5,RESULT(r1)
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl do_bad_slb_fault
|
||||
b interrupt_return
|
||||
|
@ -1538,15 +1475,13 @@ EXC_VIRT_BEGIN(instruction_access, 0x4400, 0x80)
|
|||
EXC_VIRT_END(instruction_access, 0x4400, 0x80)
|
||||
EXC_COMMON_BEGIN(instruction_access_common)
|
||||
GEN_COMMON instruction_access
|
||||
ld r4,_DAR(r1)
|
||||
ld r5,_DSISR(r1)
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
BEGIN_MMU_FTR_SECTION
|
||||
ld r6,_MSR(r1)
|
||||
li r3,0x400
|
||||
b do_hash_page /* Try to handle as hpte fault */
|
||||
bl do_hash_fault
|
||||
MMU_FTR_SECTION_ELSE
|
||||
b handle_page_fault
|
||||
bl do_page_fault
|
||||
ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX)
|
||||
b interrupt_return
|
||||
|
||||
GEN_KVM instruction_access
|
||||
|
||||
|
@ -1562,8 +1497,6 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX)
|
|||
*/
|
||||
INT_DEFINE_BEGIN(instruction_access_slb)
|
||||
IVEC=0x480
|
||||
IAREA=PACA_EXSLB
|
||||
IRECONCILE=0
|
||||
IISIDE=1
|
||||
IDAR=1
|
||||
#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
|
||||
|
@ -1579,10 +1512,9 @@ EXC_VIRT_BEGIN(instruction_access_slb, 0x4480, 0x80)
|
|||
EXC_VIRT_END(instruction_access_slb, 0x4480, 0x80)
|
||||
EXC_COMMON_BEGIN(instruction_access_slb_common)
|
||||
GEN_COMMON instruction_access_slb
|
||||
ld r4,_DAR(r1)
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
BEGIN_MMU_FTR_SECTION
|
||||
/* HPT case, do SLB fault */
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl do_slb_fault
|
||||
cmpdi r3,0
|
||||
bne- 1f
|
||||
|
@ -1593,9 +1525,6 @@ MMU_FTR_SECTION_ELSE
|
|||
li r3,-EFAULT
|
||||
ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX)
|
||||
std r3,RESULT(r1)
|
||||
RECONCILE_IRQ_STATE(r10, r11)
|
||||
ld r4,_DAR(r1)
|
||||
ld r5,RESULT(r1)
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl do_bad_slb_fault
|
||||
b interrupt_return
|
||||
|
@ -1643,7 +1572,6 @@ EXC_VIRT_END(hardware_interrupt, 0x4500, 0x100)
|
|||
EXC_COMMON_BEGIN(hardware_interrupt_common)
|
||||
GEN_COMMON hardware_interrupt
|
||||
FINISH_NAP
|
||||
RUNLATCH_ON
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl do_IRQ
|
||||
b interrupt_return
|
||||
|
@ -1697,6 +1625,51 @@ INT_DEFINE_BEGIN(program_check)
|
|||
INT_DEFINE_END(program_check)
|
||||
|
||||
EXC_REAL_BEGIN(program_check, 0x700, 0x100)
|
||||
|
||||
#ifdef CONFIG_CPU_LITTLE_ENDIAN
|
||||
/*
|
||||
* There's a short window during boot where although the kernel is
|
||||
* running little endian, any exceptions will cause the CPU to switch
|
||||
* back to big endian. For example a WARN() boils down to a trap
|
||||
* instruction, which will cause a program check, and we end up here but
|
||||
* with the CPU in big endian mode. The first instruction of the program
|
||||
* check handler (in GEN_INT_ENTRY below) is an mtsprg, which when
|
||||
* executed in the wrong endian is an lhzu with a ~3GB displacement from
|
||||
* r3. The content of r3 is random, so that is a load from some random
|
||||
* location, and depending on the system can easily lead to a checkstop,
|
||||
* or an infinitely recursive page fault.
|
||||
*
|
||||
* So to handle that case we have a trampoline here that can detect we
|
||||
* are in the wrong endian and flip us back to the correct endian. We
|
||||
* can't flip MSR[LE] using mtmsr, so we have to use rfid. That requires
|
||||
* backing up SRR0/1 as well as a GPR. To do that we use SPRG0/2/3, as
|
||||
* SPRG1 is already used for the paca. SPRG3 is user readable, but this
|
||||
* trampoline is only active very early in boot, and SPRG3 will be
|
||||
* reinitialised in vdso_getcpu_init() before userspace starts.
|
||||
*/
|
||||
BEGIN_FTR_SECTION
|
||||
tdi 0,0,0x48 // Trap never, or in reverse endian: b . + 8
|
||||
b 1f // Skip trampoline if endian is correct
|
||||
.long 0xa643707d // mtsprg 0, r11 Backup r11
|
||||
.long 0xa6027a7d // mfsrr0 r11
|
||||
.long 0xa643727d // mtsprg 2, r11 Backup SRR0 in SPRG2
|
||||
.long 0xa6027b7d // mfsrr1 r11
|
||||
.long 0xa643737d // mtsprg 3, r11 Backup SRR1 in SPRG3
|
||||
.long 0xa600607d // mfmsr r11
|
||||
.long 0x01006b69 // xori r11, r11, 1 Invert MSR[LE]
|
||||
.long 0xa6037b7d // mtsrr1 r11
|
||||
.long 0x34076039 // li r11, 0x734
|
||||
.long 0xa6037a7d // mtsrr0 r11
|
||||
.long 0x2400004c // rfid
|
||||
mfsprg r11, 3
|
||||
mtsrr1 r11 // Restore SRR1
|
||||
mfsprg r11, 2
|
||||
mtsrr0 r11 // Restore SRR0
|
||||
mfsprg r11, 0 // Restore r11
|
||||
1:
|
||||
END_FTR_SECTION(0, 1) // nop out after boot
|
||||
#endif /* CONFIG_CPU_LITTLE_ENDIAN */
|
||||
|
||||
GEN_INT_ENTRY program_check, virt=0
|
||||
EXC_REAL_END(program_check, 0x700, 0x100)
|
||||
EXC_VIRT_BEGIN(program_check, 0x4700, 0x100)
|
||||
|
@ -1755,7 +1728,6 @@ EXC_COMMON_BEGIN(program_check_common)
|
|||
*/
|
||||
INT_DEFINE_BEGIN(fp_unavailable)
|
||||
IVEC=0x800
|
||||
IRECONCILE=0
|
||||
#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
|
||||
IKVM_REAL=1
|
||||
#endif
|
||||
|
@ -1770,7 +1742,6 @@ EXC_VIRT_END(fp_unavailable, 0x4800, 0x100)
|
|||
EXC_COMMON_BEGIN(fp_unavailable_common)
|
||||
GEN_COMMON fp_unavailable
|
||||
bne 1f /* if from user, just load it up */
|
||||
RECONCILE_IRQ_STATE(r10, r11)
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl kernel_fp_unavailable_exception
|
||||
0: trap
|
||||
|
@ -1789,7 +1760,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM)
|
|||
b fast_interrupt_return
|
||||
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
||||
2: /* User process was in a transaction */
|
||||
RECONCILE_IRQ_STATE(r10, r11)
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl fp_unavailable_tm
|
||||
b interrupt_return
|
||||
|
@ -1832,7 +1802,6 @@ EXC_VIRT_END(decrementer, 0x4900, 0x80)
|
|||
EXC_COMMON_BEGIN(decrementer_common)
|
||||
GEN_COMMON decrementer
|
||||
FINISH_NAP
|
||||
RUNLATCH_ON
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl timer_interrupt
|
||||
b interrupt_return
|
||||
|
@ -1854,7 +1823,6 @@ INT_DEFINE_BEGIN(hdecrementer)
|
|||
IVEC=0x980
|
||||
IHSRR=1
|
||||
ISTACK=0
|
||||
IRECONCILE=0
|
||||
IKVM_REAL=1
|
||||
IKVM_VIRT=1
|
||||
INT_DEFINE_END(hdecrementer)
|
||||
|
@ -1919,12 +1887,11 @@ EXC_VIRT_END(doorbell_super, 0x4a00, 0x100)
|
|||
EXC_COMMON_BEGIN(doorbell_super_common)
|
||||
GEN_COMMON doorbell_super
|
||||
FINISH_NAP
|
||||
RUNLATCH_ON
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
#ifdef CONFIG_PPC_DOORBELL
|
||||
bl doorbell_exception
|
||||
#else
|
||||
bl unknown_exception
|
||||
bl unknown_async_exception
|
||||
#endif
|
||||
b interrupt_return
|
||||
|
||||
|
@ -2001,12 +1968,9 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
|
|||
HMT_MEDIUM
|
||||
|
||||
.if ! \virt
|
||||
__LOAD_HANDLER(r10, system_call_common)
|
||||
mtspr SPRN_SRR0,r10
|
||||
ld r10,PACAKMSR(r13)
|
||||
mtspr SPRN_SRR1,r10
|
||||
RFI_TO_KERNEL
|
||||
b . /* prevent speculative execution */
|
||||
__LOAD_HANDLER(r10, system_call_common_real)
|
||||
mtctr r10
|
||||
bctr
|
||||
.else
|
||||
li r10,MSR_RI
|
||||
mtmsrd r10,1 /* Set RI (EE=0) */
|
||||
|
@ -2137,9 +2101,7 @@ EXC_COMMON_BEGIN(h_data_storage_common)
|
|||
GEN_COMMON h_data_storage
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
BEGIN_MMU_FTR_SECTION
|
||||
ld r4,_DAR(r1)
|
||||
li r5,SIGSEGV
|
||||
bl bad_page_fault
|
||||
bl do_bad_page_fault_segv
|
||||
MMU_FTR_SECTION_ELSE
|
||||
bl unknown_exception
|
||||
ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_TYPE_RADIX)
|
||||
|
@ -2230,7 +2192,6 @@ INT_DEFINE_BEGIN(hmi_exception_early)
|
|||
IHSRR=1
|
||||
IREALMODE_COMMON=1
|
||||
ISTACK=0
|
||||
IRECONCILE=0
|
||||
IKUAP=0 /* We don't touch AMR here, we never go to virtual mode */
|
||||
IKVM_REAL=1
|
||||
INT_DEFINE_END(hmi_exception_early)
|
||||
|
@ -2277,7 +2238,6 @@ EXC_COMMON_BEGIN(hmi_exception_early_common)
|
|||
EXC_COMMON_BEGIN(hmi_exception_common)
|
||||
GEN_COMMON hmi_exception
|
||||
FINISH_NAP
|
||||
RUNLATCH_ON
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl handle_hmi_exception
|
||||
b interrupt_return
|
||||
|
@ -2307,12 +2267,11 @@ EXC_VIRT_END(h_doorbell, 0x4e80, 0x20)
|
|||
EXC_COMMON_BEGIN(h_doorbell_common)
|
||||
GEN_COMMON h_doorbell
|
||||
FINISH_NAP
|
||||
RUNLATCH_ON
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
#ifdef CONFIG_PPC_DOORBELL
|
||||
bl doorbell_exception
|
||||
#else
|
||||
bl unknown_exception
|
||||
bl unknown_async_exception
|
||||
#endif
|
||||
b interrupt_return
|
||||
|
||||
|
@ -2341,7 +2300,6 @@ EXC_VIRT_END(h_virt_irq, 0x4ea0, 0x20)
|
|||
EXC_COMMON_BEGIN(h_virt_irq_common)
|
||||
GEN_COMMON h_virt_irq
|
||||
FINISH_NAP
|
||||
RUNLATCH_ON
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl do_IRQ
|
||||
b interrupt_return
|
||||
|
@ -2388,7 +2346,6 @@ EXC_VIRT_END(performance_monitor, 0x4f00, 0x20)
|
|||
EXC_COMMON_BEGIN(performance_monitor_common)
|
||||
GEN_COMMON performance_monitor
|
||||
FINISH_NAP
|
||||
RUNLATCH_ON
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl performance_monitor_exception
|
||||
b interrupt_return
|
||||
|
@ -2404,7 +2361,6 @@ EXC_COMMON_BEGIN(performance_monitor_common)
|
|||
*/
|
||||
INT_DEFINE_BEGIN(altivec_unavailable)
|
||||
IVEC=0xf20
|
||||
IRECONCILE=0
|
||||
#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
|
||||
IKVM_REAL=1
|
||||
#endif
|
||||
|
@ -2434,7 +2390,6 @@ BEGIN_FTR_SECTION
|
|||
b fast_interrupt_return
|
||||
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
||||
2: /* User process was in a transaction */
|
||||
RECONCILE_IRQ_STATE(r10, r11)
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl altivec_unavailable_tm
|
||||
b interrupt_return
|
||||
|
@ -2442,7 +2397,6 @@ BEGIN_FTR_SECTION
|
|||
1:
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
|
||||
#endif
|
||||
RECONCILE_IRQ_STATE(r10, r11)
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl altivec_unavailable_exception
|
||||
b interrupt_return
|
||||
|
@ -2458,7 +2412,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
|
|||
*/
|
||||
INT_DEFINE_BEGIN(vsx_unavailable)
|
||||
IVEC=0xf40
|
||||
IRECONCILE=0
|
||||
#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
|
||||
IKVM_REAL=1
|
||||
#endif
|
||||
|
@ -2487,7 +2440,6 @@ BEGIN_FTR_SECTION
|
|||
b load_up_vsx
|
||||
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
||||
2: /* User process was in a transaction */
|
||||
RECONCILE_IRQ_STATE(r10, r11)
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl vsx_unavailable_tm
|
||||
b interrupt_return
|
||||
|
@ -2495,7 +2447,6 @@ BEGIN_FTR_SECTION
|
|||
1:
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_VSX)
|
||||
#endif
|
||||
RECONCILE_IRQ_STATE(r10, r11)
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl vsx_unavailable_exception
|
||||
b interrupt_return
|
||||
|
@ -2830,7 +2781,6 @@ EXC_VIRT_NONE(0x5800, 0x100)
|
|||
INT_DEFINE_BEGIN(soft_nmi)
|
||||
IVEC=0x900
|
||||
ISTACK=0
|
||||
IRECONCILE=0 /* Soft-NMI may fire under local_irq_disable */
|
||||
INT_DEFINE_END(soft_nmi)
|
||||
|
||||
/*
|
||||
|
@ -2849,17 +2799,6 @@ EXC_COMMON_BEGIN(soft_nmi_common)
|
|||
subi r1,r1,INT_FRAME_SIZE
|
||||
__GEN_COMMON_BODY soft_nmi
|
||||
|
||||
/*
|
||||
* Set IRQS_ALL_DISABLED and save PACAIRQHAPPENED (see
|
||||
* system_reset_common)
|
||||
*/
|
||||
li r10,IRQS_ALL_DISABLED
|
||||
stb r10,PACAIRQSOFTMASK(r13)
|
||||
lbz r10,PACAIRQHAPPENED(r13)
|
||||
std r10,RESULT(r1)
|
||||
ori r10,r10,PACA_IRQ_HARD_DIS
|
||||
stb r10,PACAIRQHAPPENED(r13)
|
||||
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl soft_nmi_interrupt
|
||||
|
||||
|
@ -2867,14 +2806,6 @@ EXC_COMMON_BEGIN(soft_nmi_common)
|
|||
li r9,0
|
||||
mtmsrd r9,1
|
||||
|
||||
/*
|
||||
* Restore soft mask settings.
|
||||
*/
|
||||
ld r10,RESULT(r1)
|
||||
stb r10,PACAIRQHAPPENED(r13)
|
||||
ld r10,SOFTE(r1)
|
||||
stb r10,PACAIRQSOFTMASK(r13)
|
||||
|
||||
kuap_kernel_restore r9, r10
|
||||
EXCEPTION_RESTORE_REGS hsrr=0
|
||||
RFI_TO_KERNEL
|
||||
|
@ -3148,9 +3079,6 @@ kvmppc_skip_Hinterrupt:
|
|||
* come here.
|
||||
*/
|
||||
|
||||
EXC_COMMON_BEGIN(ppc64_runlatch_on_trampoline)
|
||||
b __ppc64_runlatch_on
|
||||
|
||||
USE_FIXED_SECTION(virt_trampolines)
|
||||
/*
|
||||
* All code below __end_interrupts is treated as soft-masked. If
|
||||
|
@ -3221,99 +3149,3 @@ disable_machine_check:
|
|||
RFI_TO_KERNEL
|
||||
1: mtlr r0
|
||||
blr
|
||||
|
||||
/*
|
||||
* Hash table stuff
|
||||
*/
|
||||
.balign IFETCH_ALIGN_BYTES
|
||||
do_hash_page:
|
||||
#ifdef CONFIG_PPC_BOOK3S_64
|
||||
lis r0,(DSISR_BAD_FAULT_64S | DSISR_DABRMATCH | DSISR_KEYFAULT)@h
|
||||
ori r0,r0,DSISR_BAD_FAULT_64S@l
|
||||
and. r0,r5,r0 /* weird error? */
|
||||
bne- handle_page_fault /* if not, try to insert a HPTE */
|
||||
|
||||
/*
|
||||
* If we are in an "NMI" (e.g., an interrupt when soft-disabled), then
|
||||
* don't call hash_page, just fail the fault. This is required to
|
||||
* prevent re-entrancy problems in the hash code, namely perf
|
||||
* interrupts hitting while something holds H_PAGE_BUSY, and taking a
|
||||
* hash fault. See the comment in hash_preload().
|
||||
*/
|
||||
ld r11, PACA_THREAD_INFO(r13)
|
||||
lwz r0,TI_PREEMPT(r11)
|
||||
andis. r0,r0,NMI_MASK@h
|
||||
bne 77f
|
||||
|
||||
/*
|
||||
* r3 contains the trap number
|
||||
* r4 contains the faulting address
|
||||
* r5 contains dsisr
|
||||
* r6 msr
|
||||
*
|
||||
* at return r3 = 0 for success, 1 for page fault, negative for error
|
||||
*/
|
||||
bl __hash_page /* build HPTE if possible */
|
||||
cmpdi r3,0 /* see if __hash_page succeeded */
|
||||
|
||||
/* Success */
|
||||
beq interrupt_return /* Return from exception on success */
|
||||
|
||||
/* Error */
|
||||
blt- 13f
|
||||
|
||||
/* Reload DAR/DSISR into r4/r5 for the DABR check below */
|
||||
ld r4,_DAR(r1)
|
||||
ld r5,_DSISR(r1)
|
||||
#endif /* CONFIG_PPC_BOOK3S_64 */
|
||||
|
||||
/* Here we have a page fault that hash_page can't handle. */
|
||||
handle_page_fault:
|
||||
11: andis. r0,r5,DSISR_DABRMATCH@h
|
||||
bne- handle_dabr_fault
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl do_page_fault
|
||||
cmpdi r3,0
|
||||
beq+ interrupt_return
|
||||
mr r5,r3
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
ld r4,_DAR(r1)
|
||||
bl __bad_page_fault
|
||||
b interrupt_return
|
||||
|
||||
/* We have a data breakpoint exception - handle it */
|
||||
handle_dabr_fault:
|
||||
ld r4,_DAR(r1)
|
||||
ld r5,_DSISR(r1)
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl do_break
|
||||
/*
|
||||
* do_break() may have changed the NV GPRS while handling a breakpoint.
|
||||
* If so, we need to restore them with their updated values.
|
||||
*/
|
||||
REST_NVGPRS(r1)
|
||||
b interrupt_return
|
||||
|
||||
|
||||
#ifdef CONFIG_PPC_BOOK3S_64
|
||||
/* We have a page fault that hash_page could handle but HV refused
|
||||
* the PTE insertion
|
||||
*/
|
||||
13: mr r5,r3
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
ld r4,_DAR(r1)
|
||||
bl low_hash_fault
|
||||
b interrupt_return
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We come here as a result of a DSI at a point where we don't want
|
||||
* to call hash_page, such as when we are accessing memory (possibly
|
||||
* user memory) inside a PMU interrupt that occurred while interrupts
|
||||
* were soft-disabled. We want to invoke the exception handler for
|
||||
* the access, or panic if there isn't a handler.
|
||||
*/
|
||||
77: addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
li r5,SIGSEGV
|
||||
bl bad_page_fault
|
||||
b interrupt_return
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
lwz r1,TASK_STACK-THREAD(r1)
|
||||
addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE
|
||||
1:
|
||||
mtcrf 0x7f, r1
|
||||
mtcrf 0x3f, r1
|
||||
bt 32 - THREAD_ALIGN_SHIFT, stack_overflow
|
||||
#else
|
||||
subi r11, r1, INT_FRAME_SIZE /* use r1 if kernel */
|
||||
|
@ -116,114 +116,44 @@
|
|||
.endm
|
||||
|
||||
.macro SYSCALL_ENTRY trapno
|
||||
mfspr r12,SPRN_SPRG_THREAD
|
||||
mfspr r9, SPRN_SRR1
|
||||
#ifdef CONFIG_VMAP_STACK
|
||||
mfspr r11, SPRN_SRR0
|
||||
mtctr r11
|
||||
andi. r11, r9, MSR_PR
|
||||
mfspr r10, SPRN_SRR0
|
||||
LOAD_REG_IMMEDIATE(r11, MSR_KERNEL) /* can take exceptions */
|
||||
lis r12, 1f@h
|
||||
ori r12, r12, 1f@l
|
||||
mtspr SPRN_SRR1, r11
|
||||
mtspr SPRN_SRR0, r12
|
||||
mfspr r12,SPRN_SPRG_THREAD
|
||||
mr r11, r1
|
||||
lwz r1,TASK_STACK-THREAD(r12)
|
||||
beq- 99f
|
||||
addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE
|
||||
li r10, MSR_KERNEL & ~(MSR_IR | MSR_RI) /* can take DTLB miss */
|
||||
mtmsr r10
|
||||
isync
|
||||
tovirt(r12, r12)
|
||||
addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE
|
||||
rfi
|
||||
1:
|
||||
stw r11,GPR1(r1)
|
||||
stw r11,0(r1)
|
||||
mr r11, r1
|
||||
#else
|
||||
andi. r11, r9, MSR_PR
|
||||
lwz r11,TASK_STACK-THREAD(r12)
|
||||
beq- 99f
|
||||
addi r11, r11, THREAD_SIZE - INT_FRAME_SIZE
|
||||
tophys(r11, r11)
|
||||
stw r1,GPR1(r11)
|
||||
stw r1,0(r11)
|
||||
tovirt(r1, r11) /* set new kernel sp */
|
||||
#endif
|
||||
stw r10,_NIP(r11)
|
||||
mflr r10
|
||||
stw r10, _LINK(r11)
|
||||
#ifdef CONFIG_VMAP_STACK
|
||||
mfctr r10
|
||||
#else
|
||||
mfspr r10,SPRN_SRR0
|
||||
#endif
|
||||
stw r10,_NIP(r11)
|
||||
mfcr r10
|
||||
rlwinm r10,r10,0,4,2 /* Clear SO bit in CR */
|
||||
stw r10,_CCR(r11) /* save registers */
|
||||
#ifdef CONFIG_40x
|
||||
rlwinm r9,r9,0,14,12 /* clear MSR_WE (necessary?) */
|
||||
#else
|
||||
#ifdef CONFIG_VMAP_STACK
|
||||
LOAD_REG_IMMEDIATE(r10, MSR_KERNEL & ~MSR_IR) /* can take exceptions */
|
||||
#else
|
||||
LOAD_REG_IMMEDIATE(r10, MSR_KERNEL & ~(MSR_IR|MSR_DR)) /* can take exceptions */
|
||||
#endif
|
||||
mtmsr r10 /* (except for mach check in rtas) */
|
||||
#endif
|
||||
lis r10,STACK_FRAME_REGS_MARKER@ha /* exception frame marker */
|
||||
stw r2,GPR2(r11)
|
||||
addi r10,r10,STACK_FRAME_REGS_MARKER@l
|
||||
stw r9,_MSR(r11)
|
||||
li r2, \trapno + 1
|
||||
li r2, \trapno
|
||||
stw r10,8(r11)
|
||||
stw r2,_TRAP(r11)
|
||||
SAVE_GPR(0, r11)
|
||||
SAVE_4GPRS(3, r11)
|
||||
SAVE_2GPRS(7, r11)
|
||||
addi r11,r1,STACK_FRAME_OVERHEAD
|
||||
addi r2,r12,-THREAD
|
||||
stw r11,PT_REGS(r12)
|
||||
#if defined(CONFIG_40x)
|
||||
/* Check to see if the dbcr0 register is set up to debug. Use the
|
||||
internal debug mode bit to do this. */
|
||||
lwz r12,THREAD_DBCR0(r12)
|
||||
andis. r12,r12,DBCR0_IDM@h
|
||||
#endif
|
||||
ACCOUNT_CPU_USER_ENTRY(r2, r11, r12)
|
||||
#if defined(CONFIG_40x)
|
||||
beq+ 3f
|
||||
/* From user and task is ptraced - load up global dbcr0 */
|
||||
li r12,-1 /* clear all pending debug events */
|
||||
mtspr SPRN_DBSR,r12
|
||||
lis r11,global_dbcr0@ha
|
||||
tophys(r11,r11)
|
||||
addi r11,r11,global_dbcr0@l
|
||||
lwz r12,0(r11)
|
||||
mtspr SPRN_DBCR0,r12
|
||||
lwz r12,4(r11)
|
||||
addi r12,r12,-1
|
||||
stw r12,4(r11)
|
||||
#endif
|
||||
|
||||
3:
|
||||
tovirt_novmstack r2, r2 /* set r2 to current */
|
||||
lis r11, transfer_to_syscall@h
|
||||
ori r11, r11, transfer_to_syscall@l
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
/*
|
||||
* If MSR is changing we need to keep interrupts disabled at this point
|
||||
* otherwise we might risk taking an interrupt before we tell lockdep
|
||||
* they are enabled.
|
||||
*/
|
||||
LOAD_REG_IMMEDIATE(r10, MSR_KERNEL)
|
||||
rlwimi r10, r9, 0, MSR_EE
|
||||
#else
|
||||
LOAD_REG_IMMEDIATE(r10, MSR_KERNEL | MSR_EE)
|
||||
#endif
|
||||
#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PERF_EVENTS)
|
||||
mtspr SPRN_NRI, r0
|
||||
#endif
|
||||
mtspr SPRN_SRR1,r10
|
||||
mtspr SPRN_SRR0,r11
|
||||
rfi /* jump to handler, enable MMU */
|
||||
#ifdef CONFIG_40x
|
||||
b . /* Prevent prefetch past rfi */
|
||||
#endif
|
||||
99: b ret_from_kernel_syscall
|
||||
b transfer_to_syscall /* jump to handler */
|
||||
.endm
|
||||
|
||||
.macro save_dar_dsisr_on_stack reg1, reg2, sp
|
||||
|
|
|
@ -179,9 +179,9 @@ _ENTRY(saved_ksp_limit)
|
|||
*/
|
||||
START_EXCEPTION(0x0300, DataStorage)
|
||||
EXCEPTION_PROLOG
|
||||
mfspr r5, SPRN_ESR /* Grab the ESR, save it, pass arg3 */
|
||||
mfspr r5, SPRN_ESR /* Grab the ESR, save it */
|
||||
stw r5, _ESR(r11)
|
||||
mfspr r4, SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */
|
||||
mfspr r4, SPRN_DEAR /* Grab the DEAR, save it */
|
||||
stw r4, _DEAR(r11)
|
||||
EXC_XFER_LITE(0x300, handle_page_fault)
|
||||
|
||||
|
@ -191,9 +191,9 @@ _ENTRY(saved_ksp_limit)
|
|||
*/
|
||||
START_EXCEPTION(0x0400, InstructionAccess)
|
||||
EXCEPTION_PROLOG
|
||||
mr r4,r12 /* Pass SRR0 as arg2 */
|
||||
stw r4, _DEAR(r11)
|
||||
li r5,0 /* Pass zero as arg3 */
|
||||
li r5,0
|
||||
stw r5, _ESR(r11) /* Zero ESR */
|
||||
stw r12, _DEAR(r11) /* SRR0 as DEAR */
|
||||
EXC_XFER_LITE(0x400, handle_page_fault)
|
||||
|
||||
/* 0x0500 - External Interrupt Exception */
|
||||
|
@ -476,6 +476,7 @@ _ENTRY(saved_ksp_limit)
|
|||
|
||||
/* continue normal handling for a critical exception... */
|
||||
2: mfspr r4,SPRN_DBSR
|
||||
stw r4,_ESR(r11) /* DebugException takes DBSR in _ESR */
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
EXC_XFER_TEMPLATE(DebugException, 0x2002, \
|
||||
(MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
|
||||
|
|
|
@ -376,7 +376,7 @@ interrupt_base:
|
|||
/* Load the next available TLB index */
|
||||
lwz r13,tlb_44x_index@l(r10)
|
||||
|
||||
bne 2f /* Bail if permission mismach */
|
||||
bne 2f /* Bail if permission mismatch */
|
||||
|
||||
/* Increment, rollover, and store TLB index */
|
||||
addi r13,r13,1
|
||||
|
@ -471,7 +471,7 @@ interrupt_base:
|
|||
/* Load the next available TLB index */
|
||||
lwz r13,tlb_44x_index@l(r10)
|
||||
|
||||
bne 2f /* Bail if permission mismach */
|
||||
bne 2f /* Bail if permission mismatch */
|
||||
|
||||
/* Increment, rollover, and store TLB index */
|
||||
addi r13,r13,1
|
||||
|
|
|
@ -165,7 +165,7 @@ SystemCall:
|
|||
/* On the MPC8xx, this is a software emulation interrupt. It occurs
|
||||
* for all unimplemented and illegal instructions.
|
||||
*/
|
||||
EXCEPTION(0x1000, SoftEmu, program_check_exception, EXC_XFER_STD)
|
||||
EXCEPTION(0x1000, SoftEmu, emulation_assist_interrupt, EXC_XFER_STD)
|
||||
|
||||
. = 0x1100
|
||||
/*
|
||||
|
@ -312,14 +312,14 @@ DataStoreTLBMiss:
|
|||
. = 0x1300
|
||||
InstructionTLBError:
|
||||
EXCEPTION_PROLOG
|
||||
mr r4,r12
|
||||
andis. r5,r9,DSISR_SRR1_MATCH_32S@h /* Filter relevant SRR1 bits */
|
||||
andis. r10,r9,SRR1_ISI_NOPT@h
|
||||
beq+ .Litlbie
|
||||
tlbie r4
|
||||
tlbie r12
|
||||
/* 0x400 is InstructionAccess exception, needed by bad_page_fault() */
|
||||
.Litlbie:
|
||||
stw r4, _DAR(r11)
|
||||
stw r12, _DAR(r11)
|
||||
stw r5, _DSISR(r11)
|
||||
EXC_XFER_LITE(0x400, handle_page_fault)
|
||||
|
||||
/* This is the data TLB error on the MPC8xx. This could be due to
|
||||
|
@ -364,10 +364,9 @@ do_databreakpoint:
|
|||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
mfspr r4,SPRN_BAR
|
||||
stw r4,_DAR(r11)
|
||||
#ifdef CONFIG_VMAP_STACK
|
||||
lwz r5,_DSISR(r11)
|
||||
#else
|
||||
#ifndef CONFIG_VMAP_STACK
|
||||
mfspr r5,SPRN_DSISR
|
||||
stw r5,_DSISR(r11)
|
||||
#endif
|
||||
EXC_XFER_STD(0x1c00, do_break)
|
||||
|
||||
|
|
|
@ -238,8 +238,8 @@ __secondary_hold_acknowledge:
|
|||
|
||||
/* System reset */
|
||||
/* core99 pmac starts the seconary here by changing the vector, and
|
||||
putting it back to what it was (unknown_exception) when done. */
|
||||
EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD)
|
||||
putting it back to what it was (unknown_async_exception) when done. */
|
||||
EXCEPTION(0x100, Reset, unknown_async_exception, EXC_XFER_STD)
|
||||
|
||||
/* Machine check */
|
||||
/*
|
||||
|
@ -278,12 +278,6 @@ MachineCheck:
|
|||
7: EXCEPTION_PROLOG_2
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
#ifdef CONFIG_PPC_CHRP
|
||||
#ifdef CONFIG_VMAP_STACK
|
||||
mfspr r4, SPRN_SPRG_THREAD
|
||||
tovirt(r4, r4)
|
||||
lwz r4, RTAS_SP(r4)
|
||||
cmpwi cr1, r4, 0
|
||||
#endif
|
||||
beq cr1, machine_check_tramp
|
||||
twi 31, 0, 0
|
||||
#else
|
||||
|
@ -295,6 +289,7 @@ MachineCheck:
|
|||
DO_KVM 0x300
|
||||
DataAccess:
|
||||
#ifdef CONFIG_VMAP_STACK
|
||||
#ifdef CONFIG_PPC_BOOK3S_604
|
||||
BEGIN_MMU_FTR_SECTION
|
||||
mtspr SPRN_SPRG_SCRATCH2,r10
|
||||
mfspr r10, SPRN_SPRG_THREAD
|
||||
|
@ -311,12 +306,14 @@ BEGIN_MMU_FTR_SECTION
|
|||
MMU_FTR_SECTION_ELSE
|
||||
b 1f
|
||||
ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_HPTE_TABLE)
|
||||
#endif
|
||||
1: EXCEPTION_PROLOG_0 handle_dar_dsisr=1
|
||||
EXCEPTION_PROLOG_1
|
||||
b handle_page_fault_tramp_1
|
||||
#else /* CONFIG_VMAP_STACK */
|
||||
EXCEPTION_PROLOG handle_dar_dsisr=1
|
||||
get_and_save_dar_dsisr_on_stack r4, r5, r11
|
||||
#ifdef CONFIG_PPC_BOOK3S_604
|
||||
BEGIN_MMU_FTR_SECTION
|
||||
andis. r0, r5, (DSISR_BAD_FAULT_32S | DSISR_DABRMATCH)@h
|
||||
bne handle_page_fault_tramp_2 /* if not, try to put a PTE */
|
||||
|
@ -324,8 +321,11 @@ BEGIN_MMU_FTR_SECTION
|
|||
bl hash_page
|
||||
b handle_page_fault_tramp_1
|
||||
MMU_FTR_SECTION_ELSE
|
||||
#endif
|
||||
b handle_page_fault_tramp_2
|
||||
#ifdef CONFIG_PPC_BOOK3S_604
|
||||
ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_HPTE_TABLE)
|
||||
#endif
|
||||
#endif /* CONFIG_VMAP_STACK */
|
||||
|
||||
/* Instruction access exception. */
|
||||
|
@ -341,12 +341,14 @@ InstructionAccess:
|
|||
mfspr r11, SPRN_SRR1 /* check whether user or kernel */
|
||||
stw r11, SRR1(r10)
|
||||
mfcr r10
|
||||
#ifdef CONFIG_PPC_BOOK3S_604
|
||||
BEGIN_MMU_FTR_SECTION
|
||||
andis. r11, r11, SRR1_ISI_NOPT@h /* no pte found? */
|
||||
bne hash_page_isi
|
||||
.Lhash_page_isi_cont:
|
||||
mfspr r11, SPRN_SRR1 /* check whether user or kernel */
|
||||
END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE)
|
||||
#endif
|
||||
andi. r11, r11, MSR_PR
|
||||
|
||||
EXCEPTION_PROLOG_1
|
||||
|
@ -357,13 +359,15 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE)
|
|||
beq 1f /* if so, try to put a PTE */
|
||||
li r3,0 /* into the hash table */
|
||||
mr r4,r12 /* SRR0 is fault address */
|
||||
#ifdef CONFIG_PPC_BOOK3S_604
|
||||
BEGIN_MMU_FTR_SECTION
|
||||
bl hash_page
|
||||
END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE)
|
||||
#endif
|
||||
#endif /* CONFIG_VMAP_STACK */
|
||||
1: mr r4,r12
|
||||
andis. r5,r9,DSISR_SRR1_MATCH_32S@h /* Filter relevant SRR1 bits */
|
||||
stw r4, _DAR(r11)
|
||||
stw r5, _DSISR(r11)
|
||||
stw r12, _DAR(r11)
|
||||
EXC_XFER_LITE(0x400, handle_page_fault)
|
||||
|
||||
/* External interrupt */
|
||||
|
@ -640,7 +644,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
|
|||
#endif
|
||||
|
||||
#ifndef CONFIG_TAU_INT
|
||||
#define TAUException unknown_exception
|
||||
#define TAUException unknown_async_exception
|
||||
#endif
|
||||
|
||||
EXCEPTION(0x1300, Trap_13, instruction_breakpoint_exception, EXC_XFER_STD)
|
||||
|
@ -685,13 +689,16 @@ handle_page_fault_tramp_1:
|
|||
#ifdef CONFIG_VMAP_STACK
|
||||
EXCEPTION_PROLOG_2 handle_dar_dsisr=1
|
||||
#endif
|
||||
lwz r4, _DAR(r11)
|
||||
lwz r5, _DSISR(r11)
|
||||
/* fall through */
|
||||
handle_page_fault_tramp_2:
|
||||
andis. r0, r5, DSISR_DABRMATCH@h
|
||||
bne- 1f
|
||||
EXC_XFER_LITE(0x300, handle_page_fault)
|
||||
1: EXC_XFER_STD(0x300, do_break)
|
||||
|
||||
#ifdef CONFIG_VMAP_STACK
|
||||
#ifdef CONFIG_PPC_BOOK3S_604
|
||||
.macro save_regs_thread thread
|
||||
stw r0, THR0(\thread)
|
||||
stw r3, THR3(\thread)
|
||||
|
@ -763,6 +770,7 @@ fast_hash_page_return:
|
|||
mfspr r11, SPRN_SPRG_SCRATCH1
|
||||
mfspr r10, SPRN_SPRG_SCRATCH0
|
||||
rfi
|
||||
#endif /* CONFIG_PPC_BOOK3S_604 */
|
||||
|
||||
stack_overflow:
|
||||
vmap_stack_overflow_exception
|
||||
|
|
|
@ -106,10 +106,8 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_EMB_HV)
|
|||
#endif
|
||||
mfspr r9, SPRN_SRR1
|
||||
BOOKE_CLEAR_BTB(r11)
|
||||
andi. r11, r9, MSR_PR
|
||||
lwz r11, TASK_STACK - THREAD(r10)
|
||||
rlwinm r12,r12,0,4,2 /* Clear SO bit in CR */
|
||||
beq- 99f
|
||||
ALLOC_STACK_FRAME(r11, THREAD_SIZE - INT_FRAME_SIZE)
|
||||
stw r12, _CCR(r11) /* save various registers */
|
||||
mflr r12
|
||||
|
@ -124,60 +122,15 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_EMB_HV)
|
|||
stw r2,GPR2(r11)
|
||||
addi r12, r12, STACK_FRAME_REGS_MARKER@l
|
||||
stw r9,_MSR(r11)
|
||||
li r2, \trapno + 1
|
||||
li r2, \trapno
|
||||
stw r12, 8(r11)
|
||||
stw r2,_TRAP(r11)
|
||||
SAVE_GPR(0, r11)
|
||||
SAVE_4GPRS(3, r11)
|
||||
SAVE_2GPRS(7, r11)
|
||||
|
||||
addi r11,r1,STACK_FRAME_OVERHEAD
|
||||
addi r2,r10,-THREAD
|
||||
stw r11,PT_REGS(r10)
|
||||
/* Check to see if the dbcr0 register is set up to debug. Use the
|
||||
internal debug mode bit to do this. */
|
||||
lwz r12,THREAD_DBCR0(r10)
|
||||
andis. r12,r12,DBCR0_IDM@h
|
||||
ACCOUNT_CPU_USER_ENTRY(r2, r11, r12)
|
||||
beq+ 3f
|
||||
/* From user and task is ptraced - load up global dbcr0 */
|
||||
li r12,-1 /* clear all pending debug events */
|
||||
mtspr SPRN_DBSR,r12
|
||||
lis r11,global_dbcr0@ha
|
||||
tophys(r11,r11)
|
||||
addi r11,r11,global_dbcr0@l
|
||||
#ifdef CONFIG_SMP
|
||||
lwz r10, TASK_CPU(r2)
|
||||
slwi r10, r10, 3
|
||||
add r11, r11, r10
|
||||
#endif
|
||||
lwz r12,0(r11)
|
||||
mtspr SPRN_DBCR0,r12
|
||||
lwz r12,4(r11)
|
||||
addi r12,r12,-1
|
||||
stw r12,4(r11)
|
||||
|
||||
3:
|
||||
tovirt(r2, r2) /* set r2 to current */
|
||||
lis r11, transfer_to_syscall@h
|
||||
ori r11, r11, transfer_to_syscall@l
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
/*
|
||||
* If MSR is changing we need to keep interrupts disabled at this point
|
||||
* otherwise we might risk taking an interrupt before we tell lockdep
|
||||
* they are enabled.
|
||||
*/
|
||||
lis r10, MSR_KERNEL@h
|
||||
ori r10, r10, MSR_KERNEL@l
|
||||
rlwimi r10, r9, 0, MSR_EE
|
||||
#else
|
||||
lis r10, (MSR_KERNEL | MSR_EE)@h
|
||||
ori r10, r10, (MSR_KERNEL | MSR_EE)@l
|
||||
#endif
|
||||
mtspr SPRN_SRR1,r10
|
||||
mtspr SPRN_SRR0,r11
|
||||
rfi /* jump to handler, enable MMU */
|
||||
99: b ret_from_kernel_syscall
|
||||
b transfer_to_syscall /* jump to handler */
|
||||
.endm
|
||||
|
||||
/* To handle the additional exception priority levels on 40x and Book-E
|
||||
|
@ -406,6 +359,7 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_EMB_HV)
|
|||
\
|
||||
/* continue normal handling for a debug exception... */ \
|
||||
2: mfspr r4,SPRN_DBSR; \
|
||||
stw r4,_ESR(r11); /* DebugException takes DBSR in _ESR */\
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD; \
|
||||
EXC_XFER_TEMPLATE(DebugException, 0x2008, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), debug_transfer_to_handler, ret_from_debug_exc)
|
||||
|
||||
|
@ -459,6 +413,7 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_EMB_HV)
|
|||
\
|
||||
/* continue normal handling for a critical exception... */ \
|
||||
2: mfspr r4,SPRN_DBSR; \
|
||||
stw r4,_ESR(r11); /* DebugException takes DBSR in _ESR */\
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD; \
|
||||
EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), crit_transfer_to_handler, ret_from_crit_exc)
|
||||
|
||||
|
@ -476,9 +431,7 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_EMB_HV)
|
|||
NORMAL_EXCEPTION_PROLOG(INST_STORAGE); \
|
||||
mfspr r5,SPRN_ESR; /* Grab the ESR and save it */ \
|
||||
stw r5,_ESR(r11); \
|
||||
mr r4,r12; /* Pass SRR0 as arg2 */ \
|
||||
stw r4, _DEAR(r11); \
|
||||
li r5,0; /* Pass zero as arg3 */ \
|
||||
stw r12, _DEAR(r11); /* Pass SRR0 as arg2 */ \
|
||||
EXC_XFER_LITE(0x0400, handle_page_fault)
|
||||
|
||||
#define ALIGNMENT_EXCEPTION \
|
||||
|
|
|
@ -364,12 +364,12 @@ interrupt_base:
|
|||
/* Data Storage Interrupt */
|
||||
START_EXCEPTION(DataStorage)
|
||||
NORMAL_EXCEPTION_PROLOG(DATA_STORAGE)
|
||||
mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */
|
||||
mfspr r5,SPRN_ESR /* Grab the ESR, save it */
|
||||
stw r5,_ESR(r11)
|
||||
mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */
|
||||
mfspr r4,SPRN_DEAR /* Grab the DEAR, save it */
|
||||
stw r4, _DEAR(r11)
|
||||
andis. r10,r5,(ESR_ILK|ESR_DLK)@h
|
||||
bne 1f
|
||||
stw r4, _DEAR(r11)
|
||||
EXC_XFER_LITE(0x0300, handle_page_fault)
|
||||
1:
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue