Merge tag 'ASB-2024-11-05_12-5.10' of https://android.googlesource.com/kernel/common into android13-5.10-waipio

https://source.android.com/docs/security/bulletin/2024-11-01
CVE-2024-36978
CVE-2024-46740

* tag 'ASB-2024-11-05_12-5.10' of https://android.googlesource.com/kernel/common: (702 commits)
  UPSTREAM: dma-buf: heaps: Fix off-by-one in CMA heap fault handler
  BACKPORT: firmware: arm_scmi: Queue in scmi layer for mailbox implementation
  BACKPORT: gso: fix udp gso fraglist segmentation after pull from frag_list
  ANDROID: usb: Optimization the transfer rate of accessory mode in USB3.2 mode
  UPSTREAM: unicode: Don't special case ignorable code points
  ANDROID: 16K: Fixup padding vm_flags bits on VMA splits
  ANDROID: 16K: Introduce pgsize_migration_inline.h
  Revert "udf: Avoid excessive partition lengths"
  Revert "bareudp: Fix device stats updates."
  ANDROID: fix up change to pti_clone_pgtable()
  Revert "perf/aux: Fix AUX buffer serialization"
  Revert "clocksource/drivers/timer-of: Remove percpu irq related code"
  Revert "Merge 751777a79a ("nfsd: make svc_stat per-network namespace instead of global") into android12-5.10-lts"
  Revert "hwspinlock: Introduce hwspin_lock_bust()"
  Revert "bpf, cgroups: Fix cgroup v2 fallback on v1/v2 mixed mode"
  Revert "bpf, cgroup: Assign cgroup in cgroup_sk_alloc when called from interrupt"
  Linux 5.10.226
  memcg: protect concurrent access to mem_cgroup_idr
  net, sunrpc: Remap EPERM in case of connection failure in xs_tcp_setup_socket
  x86/mm: Fix PTI for i386 some more
  ...

 Conflicts:
	Documentation/devicetree/bindings/thermal/thermal-zones.yaml

Change-Id: Ic0be4604440e84cc31e9cfc7ea7d72ebc3d7d64f
This commit is contained in:
Michael Bestas 2024-11-07 10:53:18 +02:00
commit 529ffa5672
No known key found for this signature in database
GPG Key ID: CC95044519BE6669
639 changed files with 9004 additions and 6098 deletions

View File

@ -92,7 +92,7 @@ operation if the source belongs to the supported system register space.
The infrastructure emulates only the following system register space:: The infrastructure emulates only the following system register space::
Op0=3, Op1=0, CRn=0, CRm=0,4,5,6,7 Op0=3, Op1=0, CRn=0, CRm=0,2,3,4,5,6,7
(See Table C5-6 'System instruction encodings for non-Debug System (See Table C5-6 'System instruction encodings for non-Debug System
register accesses' in ARMv8 ARM DDI 0487A.h, for the list of register accesses' in ARMv8 ARM DDI 0487A.h, for the list of
@ -291,6 +291,42 @@ infrastructure:
| RPRES | [7-4] | y | | RPRES | [7-4] | y |
+------------------------------+---------+---------+ +------------------------------+---------+---------+
10) MVFR0_EL1 - AArch32 Media and VFP Feature Register 0
+------------------------------+---------+---------+
| Name | bits | visible |
+------------------------------+---------+---------+
| FPDP | [11-8] | y |
+------------------------------+---------+---------+
11) MVFR1_EL1 - AArch32 Media and VFP Feature Register 1
+------------------------------+---------+---------+
| Name | bits | visible |
+------------------------------+---------+---------+
| SIMDFMAC | [31-28] | y |
+------------------------------+---------+---------+
| SIMDSP | [19-16] | y |
+------------------------------+---------+---------+
| SIMDInt | [15-12] | y |
+------------------------------+---------+---------+
| SIMDLS | [11-8] | y |
+------------------------------+---------+---------+
12) ID_ISAR5_EL1 - AArch32 Instruction Set Attribute Register 5
+------------------------------+---------+---------+
| Name | bits | visible |
+------------------------------+---------+---------+
| CRC32 | [19-16] | y |
+------------------------------+---------+---------+
| SHA2 | [15-12] | y |
+------------------------------+---------+---------+
| SHA1 | [11-8] | y |
+------------------------------+---------+---------+
| AES | [7-4] | y |
+------------------------------+---------+---------+
Appendix I: Example Appendix I: Example
------------------- -------------------

View File

@ -94,6 +94,8 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A76 | #1463225 | ARM64_ERRATUM_1463225 | | ARM | Cortex-A76 | #1463225 | ARM64_ERRATUM_1463225 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A76 | #3324349 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A77 | #1508412 | ARM64_ERRATUM_1508412 | | ARM | Cortex-A77 | #1508412 | ARM64_ERRATUM_1508412 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A510 | #2051678 | ARM64_ERRATUM_2051678 | | ARM | Cortex-A510 | #2051678 | ARM64_ERRATUM_2051678 |
@ -102,6 +104,30 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A710 | #2054223 | ARM64_ERRATUM_2054223 | | ARM | Cortex-A710 | #2054223 | ARM64_ERRATUM_2054223 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A77 | #3324348 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A78 | #3324344 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A78C | #3324346,3324347| ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A710 | #3324338 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A720 | #3456091 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A725 | #3456106 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X1 | #3324344 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X1C | #3324346 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X2 | #3324338 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X3 | #3324335 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X4 | #3194386 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X925 | #3324334 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N1 | #1188873,1418040| ARM64_ERRATUM_1418040 | | ARM | Neoverse-N1 | #1188873,1418040| ARM64_ERRATUM_1418040 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N1 | #1349291 | N/A | | ARM | Neoverse-N1 | #1349291 | N/A |
@ -110,6 +136,16 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N2 | #2067961 | ARM64_ERRATUM_2067961 | | ARM | Neoverse-N2 | #2067961 | ARM64_ERRATUM_2067961 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N1 | #3324349 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N2 | #3324339 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-V1 | #3324341 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-V2 | #3324336 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-V3 | #3312417 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | MMU-500 | #841119,826419 | N/A | | ARM | MMU-500 | #841119,826419 | N/A |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+

View File

@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
VERSION = 5 VERSION = 5
PATCHLEVEL = 10 PATCHLEVEL = 10
SUBLEVEL = 223 SUBLEVEL = 226
EXTRAVERSION = EXTRAVERSION =
NAME = Dare mighty things NAME = Dare mighty things

View File

@ -5,31 +5,8 @@
#include "imx6q.dtsi" #include "imx6q.dtsi"
#include "imx6qdl-kontron-samx6i.dtsi" #include "imx6qdl-kontron-samx6i.dtsi"
#include <dt-bindings/gpio/gpio.h>
/ { / {
model = "Kontron SMARC sAMX6i Quad/Dual"; model = "Kontron SMARC sAMX6i Quad/Dual";
compatible = "kontron,imx6q-samx6i", "fsl,imx6q"; compatible = "kontron,imx6q-samx6i", "fsl,imx6q";
}; };
/* Quad/Dual SoMs have 3 chip-select signals */
&ecspi4 {
cs-gpios = <&gpio3 24 GPIO_ACTIVE_LOW>,
<&gpio3 29 GPIO_ACTIVE_LOW>,
<&gpio3 25 GPIO_ACTIVE_LOW>;
};
&pinctrl_ecspi4 {
fsl,pins = <
MX6QDL_PAD_EIM_D21__ECSPI4_SCLK 0x100b1
MX6QDL_PAD_EIM_D28__ECSPI4_MOSI 0x100b1
MX6QDL_PAD_EIM_D22__ECSPI4_MISO 0x100b1
/* SPI4_IMX_CS2# - connected to internal flash */
MX6QDL_PAD_EIM_D24__GPIO3_IO24 0x1b0b0
/* SPI4_IMX_CS0# - connected to SMARC SPI0_CS0# */
MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x1b0b0
/* SPI4_CS3# - connected to SMARC SPI0_CS1# */
MX6QDL_PAD_EIM_D25__GPIO3_IO25 0x1b0b0
>;
};

View File

@ -244,7 +244,8 @@ &ecspi4 {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ecspi4>; pinctrl-0 = <&pinctrl_ecspi4>;
cs-gpios = <&gpio3 24 GPIO_ACTIVE_LOW>, cs-gpios = <&gpio3 24 GPIO_ACTIVE_LOW>,
<&gpio3 29 GPIO_ACTIVE_LOW>; <&gpio3 29 GPIO_ACTIVE_LOW>,
<&gpio3 25 GPIO_ACTIVE_LOW>;
status = "okay"; status = "okay";
/* default boot source: workaround #1 for errata ERR006282 */ /* default boot source: workaround #1 for errata ERR006282 */
@ -259,8 +260,20 @@ smarc_flash: flash@0 {
&fec { &fec {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet>; pinctrl-0 = <&pinctrl_enet>;
phy-mode = "rgmii"; phy-connection-type = "rgmii-id";
phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; phy-handle = <&ethphy>;
mdio {
#address-cells = <1>;
#size-cells = <0>;
ethphy: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <1>;
reset-gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
reset-assert-us = <1000>;
};
};
}; };
&i2c_intern { &i2c_intern {
@ -448,6 +461,8 @@ MX6QDL_PAD_EIM_D22__ECSPI4_MISO 0x100b1
MX6QDL_PAD_EIM_D24__GPIO3_IO24 0x1b0b0 MX6QDL_PAD_EIM_D24__GPIO3_IO24 0x1b0b0
/* SPI_IMX_CS0# - connected to SMARC SPI0_CS0# */ /* SPI_IMX_CS0# - connected to SMARC SPI0_CS0# */
MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x1b0b0 MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x1b0b0
/* SPI4_CS3# - connected to SMARC SPI0_CS1# */
MX6QDL_PAD_EIM_D25__GPIO3_IO25 0x1b0b0
>; >;
}; };
@ -500,7 +515,7 @@ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0 MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0 MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0 MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x1b0b0 /* RST_GBE0_PHY# */ MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x1b0b0 /* RST_GBE0_PHY# */
>; >;
}; };
@ -713,7 +728,7 @@ &pcie {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pcie>; pinctrl-0 = <&pinctrl_pcie>;
wake-up-gpio = <&gpio6 18 GPIO_ACTIVE_HIGH>; wake-up-gpio = <&gpio6 18 GPIO_ACTIVE_HIGH>;
reset-gpio = <&gpio3 13 GPIO_ACTIVE_HIGH>; reset-gpio = <&gpio3 13 GPIO_ACTIVE_LOW>;
}; };
/* LCD_BKLT_PWM */ /* LCD_BKLT_PWM */
@ -801,5 +816,6 @@ &wdog1 {
/* CPLD is feeded by watchdog (hardwired) */ /* CPLD is feeded by watchdog (hardwired) */
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_wdog1>; pinctrl-0 = <&pinctrl_wdog1>;
fsl,ext-reset-output;
status = "okay"; status = "okay";
}; };

View File

@ -43,7 +43,7 @@
#include <linux/platform_data/mmc-pxamci.h> #include <linux/platform_data/mmc-pxamci.h>
#include <linux/platform_data/usb-ohci-pxa27x.h> #include <linux/platform_data/usb-ohci-pxa27x.h>
#include <linux/platform_data/video-pxafb.h> #include <linux/platform_data/video-pxafb.h>
#include <mach/spitz.h> #include "spitz.h"
#include "sharpsl_pm.h" #include "sharpsl_pm.h"
#include <mach/smemc.h> #include <mach/smemc.h>
@ -516,10 +516,8 @@ static struct pxa2xx_spi_chip spitz_ads7846_chip = {
static struct gpiod_lookup_table spitz_lcdcon_gpio_table = { static struct gpiod_lookup_table spitz_lcdcon_gpio_table = {
.dev_id = "spi2.1", .dev_id = "spi2.1",
.table = { .table = {
GPIO_LOOKUP("gpio-pxa", SPITZ_GPIO_BACKLIGHT_CONT, GPIO_LOOKUP("sharp-scoop.1", 6, "BL_CONT", GPIO_ACTIVE_LOW),
"BL_CONT", GPIO_ACTIVE_LOW), GPIO_LOOKUP("sharp-scoop.1", 7, "BL_ON", GPIO_ACTIVE_HIGH),
GPIO_LOOKUP("gpio-pxa", SPITZ_GPIO_BACKLIGHT_ON,
"BL_ON", GPIO_ACTIVE_HIGH),
{ }, { },
}, },
}; };
@ -527,10 +525,8 @@ static struct gpiod_lookup_table spitz_lcdcon_gpio_table = {
static struct gpiod_lookup_table akita_lcdcon_gpio_table = { static struct gpiod_lookup_table akita_lcdcon_gpio_table = {
.dev_id = "spi2.1", .dev_id = "spi2.1",
.table = { .table = {
GPIO_LOOKUP("gpio-pxa", AKITA_GPIO_BACKLIGHT_CONT, GPIO_LOOKUP("i2c-max7310", 3, "BL_ON", GPIO_ACTIVE_HIGH),
"BL_CONT", GPIO_ACTIVE_LOW), GPIO_LOOKUP("i2c-max7310", 4, "BL_CONT", GPIO_ACTIVE_LOW),
GPIO_LOOKUP("gpio-pxa", AKITA_GPIO_BACKLIGHT_ON,
"BL_ON", GPIO_ACTIVE_HIGH),
{ }, { },
}, },
}; };
@ -954,11 +950,36 @@ static void __init spitz_i2c_init(void)
static inline void spitz_i2c_init(void) {} static inline void spitz_i2c_init(void) {}
#endif #endif
static struct gpiod_lookup_table spitz_audio_gpio_table = {
.dev_id = "spitz-audio",
.table = {
GPIO_LOOKUP("sharp-scoop.0", 3, "mute-l", GPIO_ACTIVE_HIGH),
GPIO_LOOKUP("sharp-scoop.0", 4, "mute-r", GPIO_ACTIVE_HIGH),
GPIO_LOOKUP("sharp-scoop.1", 8, "mic", GPIO_ACTIVE_HIGH),
{ },
},
};
static struct gpiod_lookup_table akita_audio_gpio_table = {
.dev_id = "spitz-audio",
.table = {
GPIO_LOOKUP("sharp-scoop.0", 3, "mute-l", GPIO_ACTIVE_HIGH),
GPIO_LOOKUP("sharp-scoop.0", 4, "mute-r", GPIO_ACTIVE_HIGH),
GPIO_LOOKUP("i2c-max7310", 2, "mic", GPIO_ACTIVE_HIGH),
{ },
},
};
/****************************************************************************** /******************************************************************************
* Audio devices * Audio devices
******************************************************************************/ ******************************************************************************/
static inline void spitz_audio_init(void) static inline void spitz_audio_init(void)
{ {
if (machine_is_akita())
gpiod_add_lookup_table(&akita_audio_gpio_table);
else
gpiod_add_lookup_table(&spitz_audio_gpio_table);
platform_device_register_simple("spitz-audio", -1, NULL, 0); platform_device_register_simple("spitz-audio", -1, NULL, 0);
} }

View File

@ -11,7 +11,7 @@
#define __ASM_ARCH_SPITZ_H 1 #define __ASM_ARCH_SPITZ_H 1
#endif #endif
#include "irqs.h" /* PXA_NR_BUILTIN_GPIO, PXA_GPIO_TO_IRQ */ #include <mach/irqs.h> /* PXA_NR_BUILTIN_GPIO, PXA_GPIO_TO_IRQ */
#include <linux/fb.h> #include <linux/fb.h>
/* Spitz/Akita GPIOs */ /* Spitz/Akita GPIOs */

View File

@ -20,7 +20,7 @@
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/spitz.h> #include "spitz.h"
#include "pxa27x.h" #include "pxa27x.h"
#include "sharpsl_pm.h" #include "sharpsl_pm.h"

View File

@ -770,6 +770,44 @@ config ARM64_ERRATUM_2457168
If unsure, say Y. If unsure, say Y.
config ARM64_ERRATUM_3194386
bool "Cortex-*/Neoverse-*: workaround for MSR SSBS not self-synchronizing"
default y
help
This option adds the workaround for the following errata:
* ARM Cortex-A76 erratum 3324349
* ARM Cortex-A77 erratum 3324348
* ARM Cortex-A78 erratum 3324344
* ARM Cortex-A78C erratum 3324346
* ARM Cortex-A78C erratum 3324347
* ARM Cortex-A710 erratam 3324338
* ARM Cortex-A720 erratum 3456091
* ARM Cortex-A725 erratum 3456106
* ARM Cortex-X1 erratum 3324344
* ARM Cortex-X1C erratum 3324346
* ARM Cortex-X2 erratum 3324338
* ARM Cortex-X3 erratum 3324335
* ARM Cortex-X4 erratum 3194386
* ARM Cortex-X925 erratum 3324334
* ARM Neoverse-N1 erratum 3324349
* ARM Neoverse N2 erratum 3324339
* ARM Neoverse-V1 erratum 3324341
* ARM Neoverse V2 erratum 3324336
* ARM Neoverse-V3 erratum 3312417
On affected cores "MSR SSBS, #0" instructions may not affect
subsequent speculative instructions, which may permit unexepected
speculative store bypassing.
Work around this problem by placing a Speculation Barrier (SB) or
Instruction Synchronization Barrier (ISB) after kernel changes to
SSBS. The presence of the SSBS special-purpose register is hidden
from hwcaps and EL0 reads of ID_AA64PFR1_EL1, such that userspace
will use the PR_SPEC_STORE_BYPASS prctl to change SSBS.
If unsure, say Y.
config CAVIUM_ERRATUM_22375 config CAVIUM_ERRATUM_22375
bool "Cavium erratum 22375, 24313" bool "Cavium erratum 22375, 24313"
default y default y

View File

@ -311,8 +311,8 @@ &hdmi_tx {
<&reset RESET_HDMI_SYSTEM_RESET>, <&reset RESET_HDMI_SYSTEM_RESET>,
<&reset RESET_HDMI_TX>; <&reset RESET_HDMI_TX>;
reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy"; reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy";
clocks = <&clkc CLKID_HDMI_PCLK>, clocks = <&clkc CLKID_HDMI>,
<&clkc CLKID_CLK81>, <&clkc CLKID_HDMI_PCLK>,
<&clkc CLKID_GCLK_VENCI_INT0>; <&clkc CLKID_GCLK_VENCI_INT0>;
clock-names = "isfr", "iahb", "venci"; clock-names = "isfr", "iahb", "venci";
}; };

View File

@ -323,8 +323,8 @@ &hdmi_tx {
<&reset RESET_HDMI_SYSTEM_RESET>, <&reset RESET_HDMI_SYSTEM_RESET>,
<&reset RESET_HDMI_TX>; <&reset RESET_HDMI_TX>;
reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy"; reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy";
clocks = <&clkc CLKID_HDMI_PCLK>, clocks = <&clkc CLKID_HDMI>,
<&clkc CLKID_CLK81>, <&clkc CLKID_HDMI_PCLK>,
<&clkc CLKID_GCLK_VENCI_INT0>; <&clkc CLKID_GCLK_VENCI_INT0>;
clock-names = "isfr", "iahb", "venci"; clock-names = "isfr", "iahb", "venci";
}; };

View File

@ -285,8 +285,8 @@ asm_sel {
/* eMMC is shared pin with parallel NAND */ /* eMMC is shared pin with parallel NAND */
emmc_pins_default: emmc-pins-default { emmc_pins_default: emmc-pins-default {
mux { mux {
function = "emmc", "emmc_rst"; function = "emmc";
groups = "emmc"; groups = "emmc", "emmc_rst";
}; };
/* "NDL0","NDL1","NDL2","NDL3","NDL4","NDL5","NDL6","NDL7", /* "NDL0","NDL1","NDL2","NDL3","NDL4","NDL5","NDL6","NDL7",

View File

@ -249,8 +249,8 @@ &pio {
/* eMMC is shared pin with parallel NAND */ /* eMMC is shared pin with parallel NAND */
emmc_pins_default: emmc-pins-default { emmc_pins_default: emmc-pins-default {
mux { mux {
function = "emmc", "emmc_rst"; function = "emmc";
groups = "emmc"; groups = "emmc", "emmc_rst";
}; };
/* "NDL0","NDL1","NDL2","NDL3","NDL4","NDL5","NDL6","NDL7", /* "NDL0","NDL1","NDL2","NDL3","NDL4","NDL5","NDL6","NDL7",

View File

@ -628,7 +628,6 @@ pins_tx {
}; };
pins_rts { pins_rts {
pinmux = <PINMUX_GPIO47__FUNC_URTS1>; pinmux = <PINMUX_GPIO47__FUNC_URTS1>;
output-enable;
}; };
pins_cts { pins_cts {
pinmux = <PINMUX_GPIO46__FUNC_UCTS1>; pinmux = <PINMUX_GPIO46__FUNC_UCTS1>;
@ -647,7 +646,6 @@ pins_tx {
}; };
pins_rts { pins_rts {
pinmux = <PINMUX_GPIO47__FUNC_URTS1>; pinmux = <PINMUX_GPIO47__FUNC_URTS1>;
output-enable;
}; };
pins_cts { pins_cts {
pinmux = <PINMUX_GPIO46__FUNC_UCTS1>; pinmux = <PINMUX_GPIO46__FUNC_UCTS1>;

View File

@ -927,7 +927,7 @@ ufshc: ufshc@624000 {
<&gcc GCC_UFS_RX_SYMBOL_0_CLK>; <&gcc GCC_UFS_RX_SYMBOL_0_CLK>;
freq-table-hz = freq-table-hz =
<100000000 200000000>, <100000000 200000000>,
<0 0>, <100000000 200000000>,
<0 0>, <0 0>,
<0 0>, <0 0>,
<0 0>, <0 0>,

View File

@ -2125,6 +2125,8 @@ ufs_mem_phy: phy@1d87000 {
clocks = <&gcc GCC_UFS_MEM_CLKREF_CLK>, clocks = <&gcc GCC_UFS_MEM_CLKREF_CLK>,
<&gcc GCC_UFS_PHY_PHY_AUX_CLK>; <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
power-domains = <&gcc UFS_PHY_GDSC>;
resets = <&ufs_mem_hc 0>; resets = <&ufs_mem_hc 0>;
reset-names = "ufsphy"; reset-names = "ufsphy";
status = "disabled"; status = "disabled";

View File

@ -811,8 +811,8 @@ cru: clock-controller@ff440000 {
<0>, <24000000>, <0>, <24000000>,
<24000000>, <24000000>, <24000000>, <24000000>,
<15000000>, <15000000>, <15000000>, <15000000>,
<100000000>, <100000000>, <300000000>, <100000000>,
<100000000>, <100000000>, <400000000>, <100000000>,
<50000000>, <100000000>, <50000000>, <100000000>,
<100000000>, <100000000>, <100000000>, <100000000>,
<50000000>, <50000000>, <50000000>, <50000000>,

View File

@ -97,6 +97,18 @@ static inline u32 get_acpi_id_for_cpu(unsigned int cpu)
return acpi_cpu_get_madt_gicc(cpu)->uid; return acpi_cpu_get_madt_gicc(cpu)->uid;
} }
static inline int get_cpu_for_acpi_id(u32 uid)
{
int cpu;
for (cpu = 0; cpu < nr_cpu_ids; cpu++)
if (acpi_cpu_get_madt_gicc(cpu) &&
uid == get_acpi_id_for_cpu(cpu))
return cpu;
return -EINVAL;
}
static inline void arch_fix_phys_package_id(int num, u32 slot) { } static inline void arch_fix_phys_package_id(int num, u32 slot) { }
void __init acpi_init_cpus(void); void __init acpi_init_cpus(void);
int apei_claim_sea(struct pt_regs *regs); int apei_claim_sea(struct pt_regs *regs);

View File

@ -73,8 +73,9 @@
#define ARM64_SPECTRE_BHB 62 #define ARM64_SPECTRE_BHB 62
#define ARM64_WORKAROUND_2457168 63 #define ARM64_WORKAROUND_2457168 63
#define ARM64_WORKAROUND_1742098 64 #define ARM64_WORKAROUND_1742098 64
#define ARM64_WORKAROUND_SPECULATIVE_SSBS 65
/* kabi: reserve 65 - 76 for future cpu capabilities */ /* kabi: reserve 66 - 76 for future cpu capabilities */
#define ARM64_NCAPS 76 #define ARM64_NCAPS 76
#endif /* __ASM_CPUCAPS_H */ #endif /* __ASM_CPUCAPS_H */

View File

@ -84,6 +84,14 @@
#define ARM_CPU_PART_CORTEX_X2 0xD48 #define ARM_CPU_PART_CORTEX_X2 0xD48
#define ARM_CPU_PART_NEOVERSE_N2 0xD49 #define ARM_CPU_PART_NEOVERSE_N2 0xD49
#define ARM_CPU_PART_CORTEX_A78C 0xD4B #define ARM_CPU_PART_CORTEX_A78C 0xD4B
#define ARM_CPU_PART_CORTEX_X1C 0xD4C
#define ARM_CPU_PART_CORTEX_X3 0xD4E
#define ARM_CPU_PART_NEOVERSE_V2 0xD4F
#define ARM_CPU_PART_CORTEX_A720 0xD81
#define ARM_CPU_PART_CORTEX_X4 0xD82
#define ARM_CPU_PART_NEOVERSE_V3 0xD84
#define ARM_CPU_PART_CORTEX_X925 0xD85
#define ARM_CPU_PART_CORTEX_A725 0xD87
#define APM_CPU_PART_POTENZA 0x000 #define APM_CPU_PART_POTENZA 0x000
@ -136,6 +144,14 @@
#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2) #define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)
#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2) #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C) #define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C)
#define MIDR_CORTEX_X1C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1C)
#define MIDR_CORTEX_X3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X3)
#define MIDR_NEOVERSE_V2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V2)
#define MIDR_CORTEX_A720 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A720)
#define MIDR_CORTEX_X4 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X4)
#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3)
#define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925)
#define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725)
#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX) #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)

View File

@ -27,24 +27,13 @@
#include <asm/numa.h> #include <asm/numa.h>
static int acpi_early_node_map[NR_CPUS] __initdata = { NUMA_NO_NODE }; static int acpi_early_node_map[NR_CPUS] __initdata = { [0 ... NR_CPUS - 1] = NUMA_NO_NODE };
int __init acpi_numa_get_nid(unsigned int cpu) int __init acpi_numa_get_nid(unsigned int cpu)
{ {
return acpi_early_node_map[cpu]; return acpi_early_node_map[cpu];
} }
static inline int get_cpu_for_acpi_id(u32 uid)
{
int cpu;
for (cpu = 0; cpu < nr_cpu_ids; cpu++)
if (uid == get_acpi_id_for_cpu(cpu))
return cpu;
return -EINVAL;
}
static int __init acpi_parse_gicc_pxm(union acpi_subtable_headers *header, static int __init acpi_parse_gicc_pxm(union acpi_subtable_headers *header,
const unsigned long end) const unsigned long end)
{ {

View File

@ -366,6 +366,30 @@ static struct midr_range broken_aarch32_aes[] = {
}; };
#endif #endif
#ifdef CONFIG_ARM64_ERRATUM_3194386
static const struct midr_range erratum_spec_ssbs_list[] = {
MIDR_ALL_VERSIONS(MIDR_CORTEX_A76),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A77),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A720),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A725),
MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
MIDR_ALL_VERSIONS(MIDR_CORTEX_X1C),
MIDR_ALL_VERSIONS(MIDR_CORTEX_X2),
MIDR_ALL_VERSIONS(MIDR_CORTEX_X3),
MIDR_ALL_VERSIONS(MIDR_CORTEX_X4),
MIDR_ALL_VERSIONS(MIDR_CORTEX_X925),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3),
{}
};
#endif
const struct arm64_cpu_capabilities arm64_errata[] = { const struct arm64_cpu_capabilities arm64_errata[] = {
#ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE
{ {
@ -582,6 +606,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
CAP_MIDR_RANGE_LIST(broken_aarch32_aes), CAP_MIDR_RANGE_LIST(broken_aarch32_aes),
.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
}, },
#endif
#ifdef CONFIG_ARM64_ERRATUM_3194386
{
.desc = "SSBS not fully self-synchronizing",
.capability = ARM64_WORKAROUND_SPECULATIVE_SSBS,
ERRATA_MIDR_RANGE_LIST(erratum_spec_ssbs_list),
},
#endif #endif
{ {
} }

View File

@ -423,6 +423,30 @@ static const struct arm64_ftr_bits ftr_id_aa64dfr0[] = {
ARM64_FTR_END, ARM64_FTR_END,
}; };
static const struct arm64_ftr_bits ftr_mvfr0[] = {
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_FPROUND_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_FPSHVEC_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_FPSQRT_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_FPDIVIDE_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_FPTRAP_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_FPDP_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_FPSP_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_SIMD_SHIFT, 4, 0),
ARM64_FTR_END,
};
static const struct arm64_ftr_bits ftr_mvfr1[] = {
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_SIMDFMAC_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_FPHP_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_SIMDHP_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_SIMDSP_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_SIMDINT_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_SIMDLS_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_FPDNAN_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_FPFTZ_SHIFT, 4, 0),
ARM64_FTR_END,
};
static const struct arm64_ftr_bits ftr_mvfr2[] = { static const struct arm64_ftr_bits ftr_mvfr2[] = {
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR2_FPMISC_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR2_FPMISC_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR2_SIMDMISC_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR2_SIMDMISC_SHIFT, 4, 0),
@ -448,10 +472,10 @@ static const struct arm64_ftr_bits ftr_id_isar0[] = {
static const struct arm64_ftr_bits ftr_id_isar5[] = { static const struct arm64_ftr_bits ftr_id_isar5[] = {
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_RDM_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_RDM_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_CRC32_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_CRC32_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_SHA2_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_SHA2_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_SHA1_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_SHA1_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_AES_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_AES_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_SEVL_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_SEVL_SHIFT, 4, 0),
ARM64_FTR_END, ARM64_FTR_END,
}; };
@ -558,7 +582,7 @@ static const struct arm64_ftr_bits ftr_zcr[] = {
* Common ftr bits for a 32bit register with all hidden, strict * Common ftr bits for a 32bit register with all hidden, strict
* attributes, with 4bit feature fields and a default safe value of * attributes, with 4bit feature fields and a default safe value of
* 0. Covers the following 32bit registers: * 0. Covers the following 32bit registers:
* id_isar[1-4], id_mmfr[1-3], id_pfr1, mvfr[0-1] * id_isar[1-3], id_mmfr[1-3]
*/ */
static const struct arm64_ftr_bits ftr_generic_32bits[] = { static const struct arm64_ftr_bits ftr_generic_32bits[] = {
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 28, 4, 0), ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 28, 4, 0),
@ -625,8 +649,8 @@ static const struct __ftr_reg_entry {
ARM64_FTR_REG(SYS_ID_ISAR6_EL1, ftr_id_isar6), ARM64_FTR_REG(SYS_ID_ISAR6_EL1, ftr_id_isar6),
/* Op1 = 0, CRn = 0, CRm = 3 */ /* Op1 = 0, CRn = 0, CRm = 3 */
ARM64_FTR_REG(SYS_MVFR0_EL1, ftr_generic_32bits), ARM64_FTR_REG(SYS_MVFR0_EL1, ftr_mvfr0),
ARM64_FTR_REG(SYS_MVFR1_EL1, ftr_generic_32bits), ARM64_FTR_REG(SYS_MVFR1_EL1, ftr_mvfr1),
ARM64_FTR_REG(SYS_MVFR2_EL1, ftr_mvfr2), ARM64_FTR_REG(SYS_MVFR2_EL1, ftr_mvfr2),
ARM64_FTR_REG(SYS_ID_PFR2_EL1, ftr_id_pfr2), ARM64_FTR_REG(SYS_ID_PFR2_EL1, ftr_id_pfr2),
ARM64_FTR_REG(SYS_ID_DFR1_EL1, ftr_id_dfr1), ARM64_FTR_REG(SYS_ID_DFR1_EL1, ftr_id_dfr1),
@ -1292,17 +1316,39 @@ feature_matches(u64 reg, const struct arm64_cpu_capabilities *entry)
return val >= entry->min_field_value; return val >= entry->min_field_value;
} }
static u64
read_scoped_sysreg(const struct arm64_cpu_capabilities *entry, int scope)
{
WARN_ON(scope == SCOPE_LOCAL_CPU && preemptible());
if (scope == SCOPE_SYSTEM)
return read_sanitised_ftr_reg(entry->sys_reg);
else
return __read_sysreg_by_encoding(entry->sys_reg);
}
static bool
has_user_cpuid_feature(const struct arm64_cpu_capabilities *entry, int scope)
{
int mask;
struct arm64_ftr_reg *regp;
u64 val = read_scoped_sysreg(entry, scope);
regp = get_arm64_ftr_reg(entry->sys_reg);
if (!regp)
return false;
mask = cpuid_feature_extract_unsigned_field(regp->user_mask,
entry->field_pos);
if (!mask)
return false;
return feature_matches(val, entry);
}
static bool static bool
has_cpuid_feature(const struct arm64_cpu_capabilities *entry, int scope) has_cpuid_feature(const struct arm64_cpu_capabilities *entry, int scope)
{ {
u64 val; u64 val = read_scoped_sysreg(entry, scope);
WARN_ON(scope == SCOPE_LOCAL_CPU && preemptible());
if (scope == SCOPE_SYSTEM)
val = read_sanitised_ftr_reg(entry->sys_reg);
else
val = __read_sysreg_by_encoding(entry->sys_reg);
return feature_matches(val, entry); return feature_matches(val, entry);
} }
@ -1899,6 +1945,17 @@ static bool is_kvm_protected_mode(const struct arm64_cpu_capabilities *entry, in
} }
#endif /* CONFIG_KVM */ #endif /* CONFIG_KVM */
static void user_feature_fixup(void)
{
if (cpus_have_cap(ARM64_WORKAROUND_SPECULATIVE_SSBS)) {
struct arm64_ftr_reg *regp;
regp = get_arm64_ftr_reg(SYS_ID_AA64PFR1_EL1);
if (regp)
regp->user_mask &= ~GENMASK(7, 4); /* SSBS */
}
}
static void elf_hwcap_fixup(void) static void elf_hwcap_fixup(void)
{ {
#ifdef CONFIG_ARM64_ERRATUM_1742098 #ifdef CONFIG_ARM64_ERRATUM_1742098
@ -2355,7 +2412,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
}; };
#define HWCAP_CPUID_MATCH(reg, field, s, min_value) \ #define HWCAP_CPUID_MATCH(reg, field, s, min_value) \
.matches = has_cpuid_feature, \ .matches = has_user_cpuid_feature, \
.sys_reg = reg, \ .sys_reg = reg, \
.field_pos = field, \ .field_pos = field, \
.sign = s, \ .sign = s, \
@ -2929,6 +2986,7 @@ void __init setup_cpu_features(void)
u32 cwg; u32 cwg;
setup_system_capabilities(); setup_system_capabilities();
user_feature_fixup();
setup_elf_hwcaps(arm64_elf_hwcaps); setup_elf_hwcaps(arm64_elf_hwcaps);
if (system_supports_32bit_el0()) { if (system_supports_32bit_el0()) {
@ -3013,7 +3071,7 @@ static void __maybe_unused cpu_enable_cnp(struct arm64_cpu_capabilities const *c
/* /*
* We emulate only the following system register space. * We emulate only the following system register space.
* Op0 = 0x3, CRn = 0x0, Op1 = 0x0, CRm = [0, 4 - 7] * Op0 = 0x3, CRn = 0x0, Op1 = 0x0, CRm = [0, 2 - 7]
* See Table C5-6 System instruction encodings for System register accesses, * See Table C5-6 System instruction encodings for System register accesses,
* ARMv8 ARM(ARM DDI 0487A.f) for more details. * ARMv8 ARM(ARM DDI 0487A.f) for more details.
*/ */
@ -3023,7 +3081,7 @@ static inline bool __attribute_const__ is_emulated(u32 id)
sys_reg_CRn(id) == 0x0 && sys_reg_CRn(id) == 0x0 &&
sys_reg_Op1(id) == 0x0 && sys_reg_Op1(id) == 0x0 &&
(sys_reg_CRm(id) == 0 || (sys_reg_CRm(id) == 0 ||
((sys_reg_CRm(id) >= 4) && (sys_reg_CRm(id) <= 7)))); ((sys_reg_CRm(id) >= 2) && (sys_reg_CRm(id) <= 7))));
} }
/* /*

View File

@ -570,6 +570,18 @@ static enum mitigation_state spectre_v4_enable_hw_mitigation(void)
/* SCTLR_EL1.DSSBS was initialised to 0 during boot */ /* SCTLR_EL1.DSSBS was initialised to 0 during boot */
set_pstate_ssbs(0); set_pstate_ssbs(0);
/*
* SSBS is self-synchronizing and is intended to affect subsequent
* speculative instructions, but some CPUs can speculate with a stale
* value of SSBS.
*
* Mitigate this with an unconditional speculation barrier, as CPUs
* could mis-speculate branches and bypass a conditional barrier.
*/
if (IS_ENABLED(CONFIG_ARM64_ERRATUM_3194386))
spec_bar();
return SPECTRE_MITIGATED; return SPECTRE_MITIGATED;
} }

View File

@ -30,6 +30,7 @@
#include <trace/events/kvm.h> #include <trace/events/kvm.h>
#include "sys_regs.h" #include "sys_regs.h"
#include "vgic/vgic.h"
#include "trace.h" #include "trace.h"
@ -207,6 +208,11 @@ static bool access_gic_sgi(struct kvm_vcpu *vcpu,
{ {
bool g1; bool g1;
if (!kvm_has_gicv3(vcpu->kvm)) {
kvm_inject_undefined(vcpu);
return false;
}
if (!p->is_write) if (!p->is_write)
return read_from_write_only(vcpu, p, r); return read_from_write_only(vcpu, p, r);

View File

@ -318,4 +318,11 @@ int vgic_v4_init(struct kvm *kvm);
void vgic_v4_teardown(struct kvm *kvm); void vgic_v4_teardown(struct kvm *kvm);
void vgic_v4_configure_vsgis(struct kvm *kvm); void vgic_v4_configure_vsgis(struct kvm *kvm);
static inline bool kvm_has_gicv3(struct kvm *kvm)
{
return (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif) &&
irqchip_in_kernel(kvm) &&
kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3);
}
#endif #endif

View File

@ -179,6 +179,15 @@ int __init amiga_parse_bootinfo(const struct bi_record *record)
dev->slotsize = be16_to_cpu(cd->cd_SlotSize); dev->slotsize = be16_to_cpu(cd->cd_SlotSize);
dev->boardaddr = be32_to_cpu(cd->cd_BoardAddr); dev->boardaddr = be32_to_cpu(cd->cd_BoardAddr);
dev->boardsize = be32_to_cpu(cd->cd_BoardSize); dev->boardsize = be32_to_cpu(cd->cd_BoardSize);
/* CS-LAB Warp 1260 workaround */
if (be16_to_cpu(dev->rom.er_Manufacturer) == ZORRO_MANUF(ZORRO_PROD_CSLAB_WARP_1260) &&
dev->rom.er_Product == ZORRO_PROD(ZORRO_PROD_CSLAB_WARP_1260)) {
/* turn off all interrupts */
pr_info("Warp 1260 card detected: applying interrupt storm workaround\n");
*(uint32_t *)(dev->boardaddr + 0x1000) = 0xfff;
}
} else } else
pr_warn("amiga_parse_bootinfo: too many AutoConfig devices\n"); pr_warn("amiga_parse_bootinfo: too many AutoConfig devices\n");
#endif /* CONFIG_ZORRO */ #endif /* CONFIG_ZORRO */

View File

@ -302,11 +302,7 @@ void __init atari_init_IRQ(void)
if (ATARIHW_PRESENT(SCU)) { if (ATARIHW_PRESENT(SCU)) {
/* init the SCU if present */ /* init the SCU if present */
tt_scu.sys_mask = 0x10; /* enable VBL (for the cursor) and tt_scu.sys_mask = 0x0; /* disable all interrupts */
* disable HSYNC interrupts (who
* needs them?) MFP and SCC are
* enabled in VME mask
*/
tt_scu.vme_mask = 0x60; /* enable MFP and SCC ints */ tt_scu.vme_mask = 0x60; /* enable MFP and SCC ints */
} else { } else {
/* If no SCU and no Hades, the HSYNC interrupt needs to be /* If no SCU and no Hades, the HSYNC interrupt needs to be

View File

@ -33,7 +33,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
x = tmp; x = tmp;
break; break;
default: default:
tmp = __invalid_xchg_size(x, ptr, size); x = __invalid_xchg_size(x, ptr, size);
break; break;
} }

View File

@ -38,12 +38,14 @@ enum loongson_cpu_type {
Legacy_1B = 0x5, Legacy_1B = 0x5,
Legacy_2G = 0x6, Legacy_2G = 0x6,
Legacy_2H = 0x7, Legacy_2H = 0x7,
Legacy_2K = 0x8,
Loongson_1A = 0x100, Loongson_1A = 0x100,
Loongson_1B = 0x101, Loongson_1B = 0x101,
Loongson_2E = 0x200, Loongson_2E = 0x200,
Loongson_2F = 0x201, Loongson_2F = 0x201,
Loongson_2G = 0x202, Loongson_2G = 0x202,
Loongson_2H = 0x203, Loongson_2H = 0x203,
Loongson_2K = 0x204,
Loongson_3A = 0x300, Loongson_3A = 0x300,
Loongson_3B = 0x301 Loongson_3B = 0x301
}; };

View File

@ -228,6 +228,10 @@ GCR_ACCESSOR_RO(32, 0x0d0, gic_status)
GCR_ACCESSOR_RO(32, 0x0f0, cpc_status) GCR_ACCESSOR_RO(32, 0x0f0, cpc_status)
#define CM_GCR_CPC_STATUS_EX BIT(0) #define CM_GCR_CPC_STATUS_EX BIT(0)
/* GCR_ACCESS - Controls core/IOCU access to GCRs */
GCR_ACCESSOR_RW(32, 0x120, access_cm3)
#define CM_GCR_ACCESS_ACCESSEN GENMASK(7, 0)
/* GCR_L2_CONFIG - Indicates L2 cache configuration when Config5.L2C=1 */ /* GCR_L2_CONFIG - Indicates L2 cache configuration when Config5.L2C=1 */
GCR_ACCESSOR_RW(32, 0x130, l2_config) GCR_ACCESSOR_RW(32, 0x130, l2_config)
#define CM_GCR_L2_CONFIG_BYPASS BIT(20) #define CM_GCR_L2_CONFIG_BYPASS BIT(20)

View File

@ -307,13 +307,6 @@ int r4k_clockevent_init(void)
if (!c0_compare_int_usable()) if (!c0_compare_int_usable())
return -ENXIO; return -ENXIO;
/*
* With vectored interrupts things are getting platform specific.
* get_c0_compare_int is a hook to allow a platform to return the
* interrupt number of its liking.
*/
irq = get_c0_compare_int();
cd = &per_cpu(mips_clockevent_device, cpu); cd = &per_cpu(mips_clockevent_device, cpu);
cd->name = "MIPS"; cd->name = "MIPS";
@ -324,7 +317,6 @@ int r4k_clockevent_init(void)
min_delta = calculate_min_delta(); min_delta = calculate_min_delta();
cd->rating = 300; cd->rating = 300;
cd->irq = irq;
cd->cpumask = cpumask_of(cpu); cd->cpumask = cpumask_of(cpu);
cd->set_next_event = mips_next_event; cd->set_next_event = mips_next_event;
cd->event_handler = mips_event_handler; cd->event_handler = mips_event_handler;
@ -336,6 +328,13 @@ int r4k_clockevent_init(void)
cp0_timer_irq_installed = 1; cp0_timer_irq_installed = 1;
/*
* With vectored interrupts things are getting platform specific.
* get_c0_compare_int is a hook to allow a platform to return the
* interrupt number of its liking.
*/
irq = get_c0_compare_int();
if (request_irq(irq, c0_compare_interrupt, flags, "timer", if (request_irq(irq, c0_compare_interrupt, flags, "timer",
c0_compare_interrupt)) c0_compare_interrupt))
pr_err("Failed to request irq %d (timer)\n", irq); pr_err("Failed to request irq %d (timer)\n", irq);

View File

@ -1769,12 +1769,16 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu)
c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_CAM | c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_CAM |
MIPS_ASE_LOONGSON_EXT | MIPS_ASE_LOONGSON_EXT2); MIPS_ASE_LOONGSON_EXT | MIPS_ASE_LOONGSON_EXT2);
c->ases &= ~MIPS_ASE_VZ; /* VZ of Loongson-3A2000/3000 is incomplete */ c->ases &= ~MIPS_ASE_VZ; /* VZ of Loongson-3A2000/3000 is incomplete */
change_c0_config6(LOONGSON_CONF6_EXTIMER | LOONGSON_CONF6_INTIMER,
LOONGSON_CONF6_INTIMER);
break; break;
case PRID_IMP_LOONGSON_64G: case PRID_IMP_LOONGSON_64G:
__cpu_name[cpu] = "ICT Loongson-3"; __cpu_name[cpu] = "ICT Loongson-3";
set_elf_platform(cpu, "loongson3a"); set_elf_platform(cpu, "loongson3a");
set_isa(c, MIPS_CPU_ISA_M64R2); set_isa(c, MIPS_CPU_ISA_M64R2);
decode_cpucfg(c); decode_cpucfg(c);
change_c0_config6(LOONGSON_CONF6_EXTIMER | LOONGSON_CONF6_INTIMER,
LOONGSON_CONF6_INTIMER);
break; break;
default: default:
panic("Unknown Loongson Processor ID!"); panic("Unknown Loongson Processor ID!");

View File

@ -229,7 +229,10 @@ static void boot_core(unsigned int core, unsigned int vpe_id)
write_gcr_co_reset_ext_base(CM_GCR_Cx_RESET_EXT_BASE_UEB); write_gcr_co_reset_ext_base(CM_GCR_Cx_RESET_EXT_BASE_UEB);
/* Ensure the core can access the GCRs */ /* Ensure the core can access the GCRs */
set_gcr_access(1 << core); if (mips_cm_revision() < CM_REV_CM3)
set_gcr_access(1 << core);
else
set_gcr_access_cm3(1 << core);
if (mips_cpc_present()) { if (mips_cpc_present()) {
/* Reset the core */ /* Reset the core */

View File

@ -65,6 +65,12 @@ void __init prom_init_env(void)
cpu_clock_freq = ecpu->cpu_clock_freq; cpu_clock_freq = ecpu->cpu_clock_freq;
loongson_sysconf.cputype = ecpu->cputype; loongson_sysconf.cputype = ecpu->cputype;
switch (ecpu->cputype) { switch (ecpu->cputype) {
case Legacy_2K:
case Loongson_2K:
smp_group[0] = 0x900000001fe11000;
loongson_sysconf.cores_per_node = 2;
loongson_sysconf.cores_per_package = 2;
break;
case Legacy_3A: case Legacy_3A:
case Loongson_3A: case Loongson_3A:
loongson_sysconf.cores_per_node = 4; loongson_sysconf.cores_per_node = 4;
@ -213,6 +219,8 @@ void __init prom_init_env(void)
default: default:
break; break;
} }
} else if ((read_c0_prid() & PRID_IMP_MASK) == PRID_IMP_LOONGSON_64R) {
loongson_fdt_blob = __dtb_loongson64_2core_2k1000_begin;
} else if ((read_c0_prid() & PRID_IMP_MASK) == PRID_IMP_LOONGSON_64G) { } else if ((read_c0_prid() & PRID_IMP_MASK) == PRID_IMP_LOONGSON_64G) {
if (loongson_sysconf.bridgetype == LS7A) if (loongson_sysconf.bridgetype == LS7A)
loongson_fdt_blob = __dtb_loongson64g_4core_ls7a_begin; loongson_fdt_blob = __dtb_loongson64g_4core_ls7a_begin;

0
arch/mips/pci/pcie-octeon.c Executable file → Normal file
View File

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
#include <linux/io.h> #include <linux/io.h>
#include <linux/processor.h>
#include <asm/sn/ioc3.h> #include <asm/sn/ioc3.h>

View File

@ -284,6 +284,9 @@ void calibrate_delay(void)
void __init setup_arch(char **cmdline_p) void __init setup_arch(char **cmdline_p)
{ {
/* setup memblock allocator */
setup_memory();
unflatten_and_copy_device_tree(); unflatten_and_copy_device_tree();
setup_cpuinfo(); setup_cpuinfo();
@ -310,9 +313,6 @@ void __init setup_arch(char **cmdline_p)
} }
#endif #endif
/* setup memblock allocator */
setup_memory();
/* paging_init() sets up the MMU and marks all pages as reserved */ /* paging_init() sets up the MMU and marks all pages as reserved */
paging_init(); paging_init();

View File

@ -520,7 +520,7 @@ void do_cpu_irq_mask(struct pt_regs *regs)
old_regs = set_irq_regs(regs); old_regs = set_irq_regs(regs);
local_irq_disable(); local_irq_disable();
irq_enter(); irq_enter_rcu();
eirr_val = mfctl(23) & cpu_eiem & per_cpu(local_ack_eiem, cpu); eirr_val = mfctl(23) & cpu_eiem & per_cpu(local_ack_eiem, cpu);
if (!eirr_val) if (!eirr_val)
@ -555,7 +555,7 @@ void do_cpu_irq_mask(struct pt_regs *regs)
#endif /* CONFIG_IRQSTACKS */ #endif /* CONFIG_IRQSTACKS */
out: out:
irq_exit(); irq_exit_rcu();
set_irq_regs(old_regs); set_irq_regs(old_regs);
return; return;

View File

@ -114,8 +114,11 @@ static void *simple_realloc(void *ptr, unsigned long size)
return ptr; return ptr;
new = simple_malloc(size); new = simple_malloc(size);
memcpy(new, ptr, p->size); if (new) {
simple_free(ptr); memcpy(new, ptr, p->size);
simple_free(ptr);
}
return new; return new;
} }

View File

@ -24,6 +24,7 @@ CONFIG_FS_ENET=y
CONFIG_FSL_CORENET_CF=y CONFIG_FSL_CORENET_CF=y
CONFIG_FSL_DMA=y CONFIG_FSL_DMA=y
CONFIG_FSL_HV_MANAGER=y CONFIG_FSL_HV_MANAGER=y
CONFIG_FSL_IFC=y
CONFIG_FSL_PQ_MDIO=y CONFIG_FSL_PQ_MDIO=y
CONFIG_FSL_RIO=y CONFIG_FSL_RIO=y
CONFIG_FSL_XGMAC_MDIO=y CONFIG_FSL_XGMAC_MDIO=y
@ -58,6 +59,7 @@ CONFIG_INPUT_FF_MEMLESS=m
CONFIG_MARVELL_PHY=y CONFIG_MARVELL_PHY=y
CONFIG_MDIO_BUS_MUX_GPIO=y CONFIG_MDIO_BUS_MUX_GPIO=y
CONFIG_MDIO_BUS_MUX_MMIOREG=y CONFIG_MDIO_BUS_MUX_MMIOREG=y
CONFIG_MEMORY=y
CONFIG_MMC_SDHCI_OF_ESDHC=y CONFIG_MMC_SDHCI_OF_ESDHC=y
CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI=y

View File

@ -15,6 +15,16 @@
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
#endif /* __powerpc64__ */ #endif /* __powerpc64__ */
#if defined(CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK) && defined(CONFIG_SMP)
#include <linux/jump_label.h>
DECLARE_STATIC_KEY_FALSE(__percpu_first_chunk_is_paged);
#define percpu_first_chunk_is_paged \
(static_key_enabled(&__percpu_first_chunk_is_paged.key))
#else
#define percpu_first_chunk_is_paged false
#endif /* CONFIG_PPC64 && CONFIG_SMP */
#include <asm-generic/percpu.h> #include <asm-generic/percpu.h>
#include <asm/paca.h> #include <asm/paca.h>

View File

@ -594,8 +594,15 @@ long notrace machine_check_early(struct pt_regs *regs)
u8 ftrace_enabled = this_cpu_get_ftrace_enabled(); u8 ftrace_enabled = this_cpu_get_ftrace_enabled();
this_cpu_set_ftrace_enabled(0); this_cpu_set_ftrace_enabled(0);
/* Do not use nmi_enter/exit for pseries hpte guest */ /*
if (radix_enabled() || !firmware_has_feature(FW_FEATURE_LPAR)) * Do not use nmi_enter/exit for pseries hpte guest
*
* Likewise, do not use it in real mode if percpu first chunk is not
* embedded. With CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK enabled there
* are chances where percpu allocation can come from vmalloc area.
*/
if ((radix_enabled() || !firmware_has_feature(FW_FEATURE_LPAR)) &&
!percpu_first_chunk_is_paged)
nmi_enter(); nmi_enter();
hv_nmi_check_nonrecoverable(regs); hv_nmi_check_nonrecoverable(regs);
@ -606,7 +613,8 @@ long notrace machine_check_early(struct pt_regs *regs)
if (ppc_md.machine_check_early) if (ppc_md.machine_check_early)
handled = ppc_md.machine_check_early(regs); handled = ppc_md.machine_check_early(regs);
if (radix_enabled() || !firmware_has_feature(FW_FEATURE_LPAR)) if ((radix_enabled() || !firmware_has_feature(FW_FEATURE_LPAR)) &&
!percpu_first_chunk_is_paged)
nmi_exit(); nmi_exit();
this_cpu_set_ftrace_enabled(ftrace_enabled); this_cpu_set_ftrace_enabled(ftrace_enabled);

View File

@ -824,6 +824,7 @@ static int pcpu_cpu_distance(unsigned int from, unsigned int to)
unsigned long __per_cpu_offset[NR_CPUS] __read_mostly; unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
EXPORT_SYMBOL(__per_cpu_offset); EXPORT_SYMBOL(__per_cpu_offset);
DEFINE_STATIC_KEY_FALSE(__percpu_first_chunk_is_paged);
static void __init pcpu_populate_pte(unsigned long addr) static void __init pcpu_populate_pte(unsigned long addr)
{ {
@ -903,6 +904,7 @@ void __init setup_per_cpu_areas(void)
if (rc < 0) if (rc < 0)
panic("cannot initialize percpu area (err=%d)", rc); panic("cannot initialize percpu area (err=%d)", rc);
static_key_enable(&__percpu_first_chunk_is_paged.key);
delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start; delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
for_each_possible_cpu(cpu) { for_each_possible_cpu(cpu) {
__per_cpu_offset[cpu] = delta + pcpu_unit_offsets[cpu]; __per_cpu_offset[cpu] = delta + pcpu_unit_offsets[cpu];

View File

@ -835,8 +835,14 @@ void machine_check_exception(struct pt_regs *regs)
* This is silly. The BOOK3S_64 should just call a different function * This is silly. The BOOK3S_64 should just call a different function
* rather than expecting semantics to magically change. Something * rather than expecting semantics to magically change. Something
* like 'non_nmi_machine_check_exception()', perhaps? * like 'non_nmi_machine_check_exception()', perhaps?
*
* Do not use nmi_enter/exit in real mode if percpu first chunk is
* not embedded. With CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK enabled
* there are chances where percpu allocation can come from
* vmalloc area.
*/ */
const bool nmi = !IS_ENABLED(CONFIG_PPC_BOOK3S_64); const bool nmi = !IS_ENABLED(CONFIG_PPC_BOOK3S_64) &&
!percpu_first_chunk_is_paged;
if (nmi) nmi_enter(); if (nmi) nmi_enter();

View File

@ -1956,8 +1956,10 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
break; break;
r = -ENXIO; r = -ENXIO;
if (!xive_enabled()) if (!xive_enabled()) {
fdput(f);
break; break;
}
r = -EPERM; r = -EPERM;
dev = kvm_device_from_filp(f.file); dev = kvm_device_from_filp(f.file);

View File

@ -235,6 +235,8 @@ static int __init icp_native_map_one_cpu(int hw_id, unsigned long addr,
rname = kasprintf(GFP_KERNEL, "CPU %d [0x%x] Interrupt Presentation", rname = kasprintf(GFP_KERNEL, "CPU %d [0x%x] Interrupt Presentation",
cpu, hw_id); cpu, hw_id);
if (!rname)
return -ENOMEM;
if (!request_mem_region(addr, size, rname)) { if (!request_mem_region(addr, size, rname)) {
pr_warn("icp_native: Could not reserve ICP MMIO for CPU %d, interrupt server #0x%x\n", pr_warn("icp_native: Could not reserve ICP MMIO for CPU %d, interrupt server #0x%x\n",
cpu, hw_id); cpu, hw_id);

View File

@ -122,32 +122,21 @@ int print_insn_powerpc (unsigned long insn, unsigned long memaddr)
bool insn_is_short; bool insn_is_short;
ppc_cpu_t dialect; ppc_cpu_t dialect;
dialect = PPC_OPCODE_PPC | PPC_OPCODE_COMMON dialect = PPC_OPCODE_PPC | PPC_OPCODE_COMMON;
| PPC_OPCODE_64 | PPC_OPCODE_POWER4 | PPC_OPCODE_ALTIVEC;
if (cpu_has_feature(CPU_FTRS_POWER5)) if (IS_ENABLED(CONFIG_PPC64))
dialect |= PPC_OPCODE_POWER5; dialect |= PPC_OPCODE_64 | PPC_OPCODE_POWER4 | PPC_OPCODE_CELL |
PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 |
PPC_OPCODE_POWER9;
if (cpu_has_feature(CPU_FTRS_CELL)) if (cpu_has_feature(CPU_FTR_TM))
dialect |= (PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC); dialect |= PPC_OPCODE_HTM;
if (cpu_has_feature(CPU_FTRS_POWER6)) if (cpu_has_feature(CPU_FTR_ALTIVEC))
dialect |= (PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC); dialect |= PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2;
if (cpu_has_feature(CPU_FTRS_POWER7)) if (cpu_has_feature(CPU_FTR_VSX))
dialect |= (PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7 dialect |= PPC_OPCODE_VSX | PPC_OPCODE_VSX3;
| PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX);
if (cpu_has_feature(CPU_FTRS_POWER8))
dialect |= (PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7
| PPC_OPCODE_POWER8 | PPC_OPCODE_HTM
| PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2 | PPC_OPCODE_VSX);
if (cpu_has_feature(CPU_FTRS_POWER9))
dialect |= (PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7
| PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9 | PPC_OPCODE_HTM
| PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2
| PPC_OPCODE_VSX | PPC_OPCODE_VSX3);
/* Get the major opcode of the insn. */ /* Get the major opcode of the insn. */
opcode = NULL; opcode = NULL;

View File

@ -39,26 +39,27 @@ static inline void no_context(struct pt_regs *regs, unsigned long addr)
static inline void mm_fault_error(struct pt_regs *regs, unsigned long addr, vm_fault_t fault) static inline void mm_fault_error(struct pt_regs *regs, unsigned long addr, vm_fault_t fault)
{ {
if (!user_mode(regs)) {
no_context(regs, addr);
return;
}
if (fault & VM_FAULT_OOM) { if (fault & VM_FAULT_OOM) {
/* /*
* We ran out of memory, call the OOM killer, and return the userspace * We ran out of memory, call the OOM killer, and return the userspace
* (which will retry the fault, or kill us if we got oom-killed). * (which will retry the fault, or kill us if we got oom-killed).
*/ */
if (!user_mode(regs)) {
no_context(regs, addr);
return;
}
pagefault_out_of_memory(); pagefault_out_of_memory();
return; return;
} else if (fault & VM_FAULT_SIGBUS) { } else if (fault & VM_FAULT_SIGBUS) {
/* Kernel mode? Handle exceptions or die */ /* Kernel mode? Handle exceptions or die */
if (!user_mode(regs)) {
no_context(regs, addr);
return;
}
do_trap(regs, SIGBUS, BUS_ADRERR, addr); do_trap(regs, SIGBUS, BUS_ADRERR, addr);
return; return;
} else if (fault & VM_FAULT_SIGSEGV) {
do_trap(regs, SIGSEGV, SEGV_MAPERR, addr);
return;
} }
BUG(); BUG();
} }

View File

@ -312,7 +312,10 @@ static inline int share(unsigned long addr, u16 cmd)
if (!uv_call(0, (u64)&uvcb)) if (!uv_call(0, (u64)&uvcb))
return 0; return 0;
return -EINVAL; pr_err("%s UVC failed (rc: 0x%x, rrc: 0x%x), possible hypervisor bug.\n",
uvcb.header.cmd == UVC_CMD_SET_SHARED_ACCESS ? "Share" : "Unshare",
uvcb.header.rc, uvcb.header.rrc);
panic("System security cannot be guaranteed unless the system panics now.\n");
} }
/* /*

View File

@ -252,15 +252,9 @@ static inline void save_vector_registers(void)
#endif #endif
} }
static inline void setup_control_registers(void) static inline void setup_low_address_protection(void)
{ {
unsigned long reg; __ctl_set_bit(0, 28);
__ctl_store(reg, 0, 0);
reg |= CR0_LOW_ADDRESS_PROTECTION;
reg |= CR0_EMERGENCY_SIGNAL_SUBMASK;
reg |= CR0_EXTERNAL_CALL_SUBMASK;
__ctl_load(reg, 0, 0);
} }
static inline void setup_access_registers(void) static inline void setup_access_registers(void)
@ -313,7 +307,7 @@ void __init startup_init(void)
save_vector_registers(); save_vector_registers();
setup_topology(); setup_topology();
sclp_early_detect(); sclp_early_detect();
setup_control_registers(); setup_low_address_protection();
setup_access_registers(); setup_access_registers();
lockdep_on(); lockdep_on();
} }

View File

@ -982,12 +982,12 @@ void __init smp_fill_possible_mask(void)
void __init smp_prepare_cpus(unsigned int max_cpus) void __init smp_prepare_cpus(unsigned int max_cpus)
{ {
/* request the 0x1201 emergency signal external interrupt */
if (register_external_irq(EXT_IRQ_EMERGENCY_SIG, do_ext_call_interrupt)) if (register_external_irq(EXT_IRQ_EMERGENCY_SIG, do_ext_call_interrupt))
panic("Couldn't request external interrupt 0x1201"); panic("Couldn't request external interrupt 0x1201");
/* request the 0x1202 external call external interrupt */ ctl_set_bit(0, 14);
if (register_external_irq(EXT_IRQ_EXTERNAL_CALL, do_ext_call_interrupt)) if (register_external_irq(EXT_IRQ_EXTERNAL_CALL, do_ext_call_interrupt))
panic("Couldn't request external interrupt 0x1202"); panic("Couldn't request external interrupt 0x1202");
ctl_set_bit(0, 13);
} }
void __init smp_prepare_boot_cpu(void) void __init smp_prepare_boot_cpu(void)

View File

@ -69,6 +69,15 @@ SECTIONS
. = ALIGN(PAGE_SIZE); . = ALIGN(PAGE_SIZE);
__end_ro_after_init = .; __end_ro_after_init = .;
.data.rel.ro : {
*(.data.rel.ro .data.rel.ro.*)
}
.got : {
__got_start = .;
*(.got)
__got_end = .;
}
RW_DATA(0x100, PAGE_SIZE, THREAD_SIZE) RW_DATA(0x100, PAGE_SIZE, THREAD_SIZE)
BOOT_DATA_PRESERVED BOOT_DATA_PRESERVED

View File

@ -247,6 +247,7 @@ void prom_sun4v_guest_soft_state(void);
int prom_ihandle2path(int handle, char *buffer, int bufsize); int prom_ihandle2path(int handle, char *buffer, int bufsize);
/* Client interface level routines. */ /* Client interface level routines. */
void prom_cif_init(void *cif_handler);
void p1275_cmd_direct(unsigned long *); void p1275_cmd_direct(unsigned long *);
#endif /* !(__SPARC64_OPLIB_H) */ #endif /* !(__SPARC64_OPLIB_H) */

View File

@ -26,9 +26,6 @@ phandle prom_chosen_node;
* routines in the prom library. * routines in the prom library.
* It gets passed the pointer to the PROM vector. * It gets passed the pointer to the PROM vector.
*/ */
extern void prom_cif_init(void *);
void __init prom_init(void *cif_handler) void __init prom_init(void *cif_handler)
{ {
phandle node; phandle node;

View File

@ -49,7 +49,7 @@ void p1275_cmd_direct(unsigned long *args)
local_irq_restore(flags); local_irq_restore(flags);
} }
void prom_cif_init(void *cif_handler, void *cif_stack) void prom_cif_init(void *cif_handler)
{ {
p1275buf.prom_cif_handler = (void (*)(long *))cif_handler; p1275buf.prom_cif_handler = (void (*)(long *))cif_handler;
} }

View File

@ -378,6 +378,7 @@ int setup_one_line(struct line *lines, int n, char *init,
parse_chan_pair(NULL, line, n, opts, error_out); parse_chan_pair(NULL, line, n, opts, error_out);
err = 0; err = 0;
} }
*error_out = "configured as 'none'";
} else { } else {
char *new = kstrdup(init, GFP_KERNEL); char *new = kstrdup(init, GFP_KERNEL);
if (!new) { if (!new) {
@ -401,6 +402,7 @@ int setup_one_line(struct line *lines, int n, char *init,
} }
} }
if (err) { if (err) {
*error_out = "failed to parse channel pair";
line->init_str = NULL; line->init_str = NULL;
line->valid = 0; line->valid = 0;
kfree(new); kfree(new);

View File

@ -756,9 +756,9 @@ int setup_time_travel_start(char *str)
return 1; return 1;
} }
__setup("time-travel-start", setup_time_travel_start); __setup("time-travel-start=", setup_time_travel_start);
__uml_help(setup_time_travel_start, __uml_help(setup_time_travel_start,
"time-travel-start=<seconds>\n" "time-travel-start=<nanoseconds>\n"
"Configure the UML instance's wall clock to start at this value rather than\n" "Configure the UML instance's wall clock to start at this value rather than\n"
"the host's wall clock at the time of UML boot.\n"); "the host's wall clock at the time of UML boot.\n");
#endif #endif

View File

@ -861,7 +861,7 @@ static void pt_update_head(struct pt *pt)
*/ */
static void *pt_buffer_region(struct pt_buffer *buf) static void *pt_buffer_region(struct pt_buffer *buf)
{ {
return phys_to_virt(TOPA_ENTRY(buf->cur, buf->cur_idx)->base << TOPA_SHIFT); return phys_to_virt((phys_addr_t)TOPA_ENTRY(buf->cur, buf->cur_idx)->base << TOPA_SHIFT);
} }
/** /**
@ -973,7 +973,7 @@ pt_topa_entry_for_page(struct pt_buffer *buf, unsigned int pg)
* order allocations, there shouldn't be many of these. * order allocations, there shouldn't be many of these.
*/ */
list_for_each_entry(topa, &buf->tables, list) { list_for_each_entry(topa, &buf->tables, list) {
if (topa->offset + topa->size > pg << PAGE_SHIFT) if (topa->offset + topa->size > (unsigned long)pg << PAGE_SHIFT)
goto found; goto found;
} }

View File

@ -33,8 +33,8 @@ struct topa_entry {
u64 rsvd2 : 1; u64 rsvd2 : 1;
u64 size : 4; u64 size : 4;
u64 rsvd3 : 2; u64 rsvd3 : 2;
u64 base : 36; u64 base : 40;
u64 rsvd4 : 16; u64 rsvd4 : 12;
}; };
/* TSC to Core Crystal Clock Ratio */ /* TSC to Core Crystal Clock Ratio */

View File

@ -817,7 +817,7 @@ void mtrr_save_state(void)
{ {
int first_cpu; int first_cpu;
if (!mtrr_enabled()) if (!mtrr_enabled() || !mtrr_state.have_fixed)
return; return;
first_cpu = cpumask_first(cpu_online_mask); first_cpu = cpumask_first(cpu_online_mask);

View File

@ -92,7 +92,7 @@ static int x86_of_pci_irq_enable(struct pci_dev *dev)
ret = pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); ret = pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
if (ret) if (ret)
return ret; return pcibios_err_to_errno(ret);
if (!pin) if (!pin)
return 0; return 0;

View File

@ -926,7 +926,10 @@ unsigned long arch_align_stack(unsigned long sp)
unsigned long arch_randomize_brk(struct mm_struct *mm) unsigned long arch_randomize_brk(struct mm_struct *mm)
{ {
return randomize_page(mm->brk, 0x02000000); if (mmap_is_ia32())
return randomize_page(mm->brk, SZ_32M);
return randomize_page(mm->brk, SZ_1G);
} }
/* /*

View File

@ -4738,14 +4738,19 @@ static int vmx_nmi_allowed(struct kvm_vcpu *vcpu, bool for_injection)
return !vmx_nmi_blocked(vcpu); return !vmx_nmi_blocked(vcpu);
} }
bool __vmx_interrupt_blocked(struct kvm_vcpu *vcpu)
{
return !(vmx_get_rflags(vcpu) & X86_EFLAGS_IF) ||
(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) &
(GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS));
}
bool vmx_interrupt_blocked(struct kvm_vcpu *vcpu) bool vmx_interrupt_blocked(struct kvm_vcpu *vcpu)
{ {
if (is_guest_mode(vcpu) && nested_exit_on_intr(vcpu)) if (is_guest_mode(vcpu) && nested_exit_on_intr(vcpu))
return false; return false;
return !(vmx_get_rflags(vcpu) & X86_EFLAGS_IF) || return __vmx_interrupt_blocked(vcpu);
(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) &
(GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS));
} }
static int vmx_interrupt_allowed(struct kvm_vcpu *vcpu, bool for_injection) static int vmx_interrupt_allowed(struct kvm_vcpu *vcpu, bool for_injection)

View File

@ -359,6 +359,7 @@ bool vmx_guest_inject_ac(struct kvm_vcpu *vcpu);
void update_exception_bitmap(struct kvm_vcpu *vcpu); void update_exception_bitmap(struct kvm_vcpu *vcpu);
void vmx_update_msr_bitmap(struct kvm_vcpu *vcpu); void vmx_update_msr_bitmap(struct kvm_vcpu *vcpu);
bool vmx_nmi_blocked(struct kvm_vcpu *vcpu); bool vmx_nmi_blocked(struct kvm_vcpu *vcpu);
bool __vmx_interrupt_blocked(struct kvm_vcpu *vcpu);
bool vmx_interrupt_blocked(struct kvm_vcpu *vcpu); bool vmx_interrupt_blocked(struct kvm_vcpu *vcpu);
bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu); bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu);
void vmx_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked); void vmx_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked);

View File

@ -241,7 +241,7 @@ static pmd_t *pti_user_pagetable_walk_pmd(unsigned long address)
* *
* Returns a pointer to a PTE on success, or NULL on failure. * Returns a pointer to a PTE on success, or NULL on failure.
*/ */
static pte_t *pti_user_pagetable_walk_pte(unsigned long address) static pte_t *pti_user_pagetable_walk_pte(unsigned long address, bool late_text)
{ {
gfp_t gfp = (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO); gfp_t gfp = (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO);
pmd_t *pmd; pmd_t *pmd;
@ -251,10 +251,15 @@ static pte_t *pti_user_pagetable_walk_pte(unsigned long address)
if (!pmd) if (!pmd)
return NULL; return NULL;
/* We can't do anything sensible if we hit a large mapping. */ /* Large PMD mapping found */
if (pmd_large(*pmd)) { if (pmd_large(*pmd)) {
WARN_ON(1); /* Clear the PMD if we hit a large mapping from the first round */
return NULL; if (late_text) {
set_pmd(pmd, __pmd(0));
} else {
WARN_ON_ONCE(1);
return NULL;
}
} }
if (pmd_none(*pmd)) { if (pmd_none(*pmd)) {
@ -283,7 +288,7 @@ static void __init pti_setup_vsyscall(void)
if (!pte || WARN_ON(level != PG_LEVEL_4K) || pte_none(*pte)) if (!pte || WARN_ON(level != PG_LEVEL_4K) || pte_none(*pte))
return; return;
target_pte = pti_user_pagetable_walk_pte(VSYSCALL_ADDR); target_pte = pti_user_pagetable_walk_pte(VSYSCALL_ADDR, false);
if (WARN_ON(!target_pte)) if (WARN_ON(!target_pte))
return; return;
@ -301,7 +306,7 @@ enum pti_clone_level {
static void static void
pti_clone_pgtable(unsigned long start, unsigned long end, pti_clone_pgtable(unsigned long start, unsigned long end,
enum pti_clone_level level) enum pti_clone_level level, bool late_text)
{ {
unsigned long addr; unsigned long addr;
@ -374,14 +379,14 @@ pti_clone_pgtable(unsigned long start, unsigned long end,
*/ */
*target_pmd = *pmd; *target_pmd = *pmd;
addr += PMD_SIZE; addr = round_up(addr + 1, PMD_SIZE);
} else if (level == PTI_CLONE_PTE) { } else if (level == PTI_CLONE_PTE) {
/* Walk the page-table down to the pte level */ /* Walk the page-table down to the pte level */
pte = pte_offset_kernel(pmd, addr); pte = pte_offset_kernel(pmd, addr);
if (pte_none(*pte)) { if (pte_none(*pte)) {
addr += PAGE_SIZE; addr = round_up(addr + 1, PAGE_SIZE);
continue; continue;
} }
@ -390,7 +395,7 @@ pti_clone_pgtable(unsigned long start, unsigned long end,
return; return;
/* Allocate PTE in the user page-table */ /* Allocate PTE in the user page-table */
target_pte = pti_user_pagetable_walk_pte(addr); target_pte = pti_user_pagetable_walk_pte(addr, late_text);
if (WARN_ON(!target_pte)) if (WARN_ON(!target_pte))
return; return;
@ -401,7 +406,7 @@ pti_clone_pgtable(unsigned long start, unsigned long end,
/* Clone the PTE */ /* Clone the PTE */
*target_pte = *pte; *target_pte = *pte;
addr += PAGE_SIZE; addr = round_up(addr + 1, PAGE_SIZE);
} else { } else {
BUG(); BUG();
@ -453,7 +458,7 @@ static void __init pti_clone_user_shared(void)
phys_addr_t pa = per_cpu_ptr_to_phys((void *)va); phys_addr_t pa = per_cpu_ptr_to_phys((void *)va);
pte_t *target_pte; pte_t *target_pte;
target_pte = pti_user_pagetable_walk_pte(va); target_pte = pti_user_pagetable_walk_pte(va, false);
if (WARN_ON(!target_pte)) if (WARN_ON(!target_pte))
return; return;
@ -476,7 +481,7 @@ static void __init pti_clone_user_shared(void)
start = CPU_ENTRY_AREA_BASE; start = CPU_ENTRY_AREA_BASE;
end = start + (PAGE_SIZE * CPU_ENTRY_AREA_PAGES); end = start + (PAGE_SIZE * CPU_ENTRY_AREA_PAGES);
pti_clone_pgtable(start, end, PTI_CLONE_PMD); pti_clone_pgtable(start, end, PTI_CLONE_PMD, false);
} }
#endif /* CONFIG_X86_64 */ #endif /* CONFIG_X86_64 */
@ -493,11 +498,11 @@ static void __init pti_setup_espfix64(void)
/* /*
* Clone the populated PMDs of the entry text and force it RO. * Clone the populated PMDs of the entry text and force it RO.
*/ */
static void pti_clone_entry_text(void) static void pti_clone_entry_text(bool late)
{ {
pti_clone_pgtable((unsigned long) __entry_text_start, pti_clone_pgtable((unsigned long) __entry_text_start,
(unsigned long) __entry_text_end, (unsigned long) __entry_text_end,
PTI_CLONE_PMD); PTI_LEVEL_KERNEL_IMAGE, late);
/* /*
* If CFI is enabled, also map jump tables, so the entry code can * If CFI is enabled, also map jump tables, so the entry code can
@ -506,7 +511,7 @@ static void pti_clone_entry_text(void)
if (IS_ENABLED(CONFIG_CFI_CLANG)) if (IS_ENABLED(CONFIG_CFI_CLANG))
pti_clone_pgtable((unsigned long) __cfi_jt_start, pti_clone_pgtable((unsigned long) __cfi_jt_start,
(unsigned long) __cfi_jt_end, (unsigned long) __cfi_jt_end,
PTI_CLONE_PMD); PTI_CLONE_PMD, late);
} }
/* /*
@ -581,7 +586,7 @@ static void pti_clone_kernel_text(void)
* pti_set_kernel_image_nonglobal() did to clear the * pti_set_kernel_image_nonglobal() did to clear the
* global bit. * global bit.
*/ */
pti_clone_pgtable(start, end_clone, PTI_LEVEL_KERNEL_IMAGE); pti_clone_pgtable(start, end_clone, PTI_LEVEL_KERNEL_IMAGE, false);
/* /*
* pti_clone_pgtable() will set the global bit in any PMDs * pti_clone_pgtable() will set the global bit in any PMDs
@ -648,8 +653,15 @@ void __init pti_init(void)
/* Undo all global bits from the init pagetables in head_64.S: */ /* Undo all global bits from the init pagetables in head_64.S: */
pti_set_kernel_image_nonglobal(); pti_set_kernel_image_nonglobal();
/* Replace some of the global bits just for shared entry text: */ /* Replace some of the global bits just for shared entry text: */
pti_clone_entry_text(); /*
* This is very early in boot. Device and Late initcalls can do
* modprobe before free_initmem() and mark_readonly(). This
* pti_clone_entry_text() allows those user-mode-helpers to function,
* but notably the text is still RW.
*/
pti_clone_entry_text(false);
pti_setup_espfix64(); pti_setup_espfix64();
pti_setup_vsyscall(); pti_setup_vsyscall();
} }
@ -666,10 +678,11 @@ void pti_finalize(void)
if (!boot_cpu_has(X86_FEATURE_PTI)) if (!boot_cpu_has(X86_FEATURE_PTI))
return; return;
/* /*
* We need to clone everything (again) that maps parts of the * This is after free_initmem() (all initcalls are done) and we've done
* kernel image. * mark_readonly(). Text is now NX which might've split some PMDs
* relative to the early clone.
*/ */
pti_clone_entry_text(); pti_clone_entry_text(true);
pti_clone_kernel_text(); pti_clone_kernel_text();
debug_checkwx_user(); debug_checkwx_user();

View File

@ -223,9 +223,9 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev)
return 0; return 0;
ret = pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &gsi); ret = pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &gsi);
if (ret < 0) { if (ret) {
dev_warn(&dev->dev, "Failed to read interrupt line: %d\n", ret); dev_warn(&dev->dev, "Failed to read interrupt line: %d\n", ret);
return ret; return pcibios_err_to_errno(ret);
} }
switch (intel_mid_identify_cpu()) { switch (intel_mid_identify_cpu()) {

View File

@ -37,10 +37,10 @@ static int xen_pcifront_enable_irq(struct pci_dev *dev)
u8 gsi; u8 gsi;
rc = pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &gsi); rc = pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &gsi);
if (rc < 0) { if (rc) {
dev_warn(&dev->dev, "Xen PCI: failed to read interrupt line: %d\n", dev_warn(&dev->dev, "Xen PCI: failed to read interrupt line: %d\n",
rc); rc);
return rc; return pcibios_err_to_errno(rc);
} }
/* In PV DomU the Xen PCI backend puts the PIRQ in the interrupt line.*/ /* In PV DomU the Xen PCI backend puts the PIRQ in the interrupt line.*/
pirq = gsi; pirq = gsi;

View File

@ -62,7 +62,7 @@ static int iosf_mbi_pci_read_mdr(u32 mcrx, u32 mcr, u32 *mdr)
fail_read: fail_read:
dev_err(&mbi_pdev->dev, "PCI config access failed with %d\n", result); dev_err(&mbi_pdev->dev, "PCI config access failed with %d\n", result);
return result; return pcibios_err_to_errno(result);
} }
static int iosf_mbi_pci_write_mdr(u32 mcrx, u32 mcr, u32 mdr) static int iosf_mbi_pci_write_mdr(u32 mcrx, u32 mcr, u32 mdr)
@ -91,7 +91,7 @@ static int iosf_mbi_pci_write_mdr(u32 mcrx, u32 mcr, u32 mdr)
fail_write: fail_write:
dev_err(&mbi_pdev->dev, "PCI config access failed with %d\n", result); dev_err(&mbi_pdev->dev, "PCI config access failed with %d\n", result);
return result; return pcibios_err_to_errno(result);
} }
int iosf_mbi_read(u8 port, u8 opcode, u32 offset, u32 *mdr) int iosf_mbi_read(u8 port, u8 opcode, u32 offset, u32 *mdr)

View File

@ -736,7 +736,7 @@ int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
* immediate unmapping. * immediate unmapping.
*/ */
map_ops[i].status = GNTST_general_error; map_ops[i].status = GNTST_general_error;
unmap[0].host_addr = map_ops[i].host_addr, unmap[0].host_addr = map_ops[i].host_addr;
unmap[0].handle = map_ops[i].handle; unmap[0].handle = map_ops[i].handle;
map_ops[i].handle = ~0; map_ops[i].handle = ~0;
if (map_ops[i].flags & GNTMAP_device_map) if (map_ops[i].flags & GNTMAP_device_map)
@ -746,7 +746,7 @@ int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
if (kmap_ops) { if (kmap_ops) {
kmap_ops[i].status = GNTST_general_error; kmap_ops[i].status = GNTST_general_error;
unmap[1].host_addr = kmap_ops[i].host_addr, unmap[1].host_addr = kmap_ops[i].host_addr;
unmap[1].handle = kmap_ops[i].handle; unmap[1].handle = kmap_ops[i].handle;
kmap_ops[i].handle = ~0; kmap_ops[i].handle = ~0;
if (kmap_ops[i].flags & GNTMAP_device_map) if (kmap_ops[i].flags & GNTMAP_device_map)

View File

@ -216,6 +216,7 @@ bool bio_integrity_prep(struct bio *bio)
unsigned int bytes, offset, i; unsigned int bytes, offset, i;
unsigned int intervals; unsigned int intervals;
blk_status_t status; blk_status_t status;
gfp_t gfp = GFP_NOIO;
if (!bi) if (!bi)
return true; return true;
@ -238,12 +239,20 @@ bool bio_integrity_prep(struct bio *bio)
if (!bi->profile->generate_fn || if (!bi->profile->generate_fn ||
!(bi->flags & BLK_INTEGRITY_GENERATE)) !(bi->flags & BLK_INTEGRITY_GENERATE))
return true; return true;
/*
* Zero the memory allocated to not leak uninitialized kernel
* memory to disk. For PI this only affects the app tag, but
* for non-integrity metadata it affects the entire metadata
* buffer.
*/
gfp |= __GFP_ZERO;
} }
intervals = bio_integrity_intervals(bi, bio_sectors(bio)); intervals = bio_integrity_intervals(bi, bio_sectors(bio));
/* Allocate kernel buffer for protection data */ /* Allocate kernel buffer for protection data */
len = intervals * bi->tuple_size; len = intervals * bi->tuple_size;
buf = kmalloc(len, GFP_NOIO | q->bounce_gfp); buf = kmalloc(len, gfp | q->bounce_gfp);
status = BLK_STS_RESOURCE; status = BLK_STS_RESOURCE;
if (unlikely(buf == NULL)) { if (unlikely(buf == NULL)) {
printk(KERN_ERR "could not allocate integrity buffer\n"); printk(KERN_ERR "could not allocate integrity buffer\n");

View File

@ -431,8 +431,6 @@ void blk_integrity_unregister(struct gendisk *disk)
if (!bi->profile) if (!bi->profile)
return; return;
/* ensure all bios are off the integrity workqueue */
blk_flush_integrity();
blk_queue_flag_clear(QUEUE_FLAG_STABLE_WRITES, disk->queue); blk_queue_flag_clear(QUEUE_FLAG_STABLE_WRITES, disk->queue);
memset(bi, 0, sizeof(*bi)); memset(bi, 0, sizeof(*bi));
} }

View File

@ -387,7 +387,7 @@ static int acpi_processor_add(struct acpi_device *device,
result = acpi_processor_get_info(device); result = acpi_processor_get_info(device);
if (result) /* Processor is not physically present or unavailable */ if (result) /* Processor is not physically present or unavailable */
return 0; goto err_clear_driver_data;
BUG_ON(pr->id >= nr_cpu_ids); BUG_ON(pr->id >= nr_cpu_ids);
@ -402,7 +402,7 @@ static int acpi_processor_add(struct acpi_device *device,
"BIOS reported wrong ACPI id %d for the processor\n", "BIOS reported wrong ACPI id %d for the processor\n",
pr->id); pr->id);
/* Give up, but do not abort the namespace scan. */ /* Give up, but do not abort the namespace scan. */
goto err; goto err_clear_driver_data;
} }
/* /*
* processor_device_array is not cleared on errors to allow buggy BIOS * processor_device_array is not cleared on errors to allow buggy BIOS
@ -414,12 +414,12 @@ static int acpi_processor_add(struct acpi_device *device,
dev = get_cpu_device(pr->id); dev = get_cpu_device(pr->id);
if (!dev) { if (!dev) {
result = -ENODEV; result = -ENODEV;
goto err; goto err_clear_per_cpu;
} }
result = acpi_bind_one(dev, device); result = acpi_bind_one(dev, device);
if (result) if (result)
goto err; goto err_clear_per_cpu;
pr->dev = dev; pr->dev = dev;
@ -430,10 +430,11 @@ static int acpi_processor_add(struct acpi_device *device,
dev_err(dev, "Processor driver could not be attached\n"); dev_err(dev, "Processor driver could not be attached\n");
acpi_unbind_one(dev); acpi_unbind_one(dev);
err: err_clear_per_cpu:
free_cpumask_var(pr->throttling.shared_cpu_map);
device->driver_data = NULL;
per_cpu(processors, pr->id) = NULL; per_cpu(processors, pr->id) = NULL;
err_clear_driver_data:
device->driver_data = NULL;
free_cpumask_var(pr->throttling.shared_cpu_map);
err_free_pr: err_free_pr:
kfree(pr); kfree(pr);
return result; return result;

View File

@ -670,12 +670,18 @@ static ssize_t acpi_battery_alarm_store(struct device *dev,
return count; return count;
} }
static const struct device_attribute alarm_attr = { static struct device_attribute alarm_attr = {
.attr = {.name = "alarm", .mode = 0644}, .attr = {.name = "alarm", .mode = 0644},
.show = acpi_battery_alarm_show, .show = acpi_battery_alarm_show,
.store = acpi_battery_alarm_store, .store = acpi_battery_alarm_store,
}; };
static struct attribute *acpi_battery_attrs[] = {
&alarm_attr.attr,
NULL
};
ATTRIBUTE_GROUPS(acpi_battery);
/* /*
* The Battery Hooking API * The Battery Hooking API
* *
@ -812,7 +818,10 @@ static void __exit battery_hook_exit(void)
static int sysfs_add_battery(struct acpi_battery *battery) static int sysfs_add_battery(struct acpi_battery *battery)
{ {
struct power_supply_config psy_cfg = { .drv_data = battery, }; struct power_supply_config psy_cfg = {
.drv_data = battery,
.attr_grp = acpi_battery_groups,
};
bool full_cap_broken = false; bool full_cap_broken = false;
if (!ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity) && if (!ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity) &&
@ -857,7 +866,7 @@ static int sysfs_add_battery(struct acpi_battery *battery)
return result; return result;
} }
battery_hook_add_battery(battery); battery_hook_add_battery(battery);
return device_create_file(&battery->bat->dev, &alarm_attr); return 0;
} }
static void sysfs_remove_battery(struct acpi_battery *battery) static void sysfs_remove_battery(struct acpi_battery *battery)
@ -868,7 +877,6 @@ static void sysfs_remove_battery(struct acpi_battery *battery)
return; return;
} }
battery_hook_remove_battery(battery); battery_hook_remove_battery(battery);
device_remove_file(&battery->bat->dev, &alarm_attr);
power_supply_unregister(battery->bat); power_supply_unregister(battery->bat);
battery->bat = NULL; battery->bat = NULL;
mutex_unlock(&battery->sysfs_lock); mutex_unlock(&battery->sysfs_lock);

View File

@ -77,7 +77,6 @@ struct acpi_battery {
u16 spec; u16 spec;
u8 id; u8 id;
u8 present:1; u8 present:1;
u8 have_sysfs_alarm:1;
}; };
#define to_acpi_battery(x) power_supply_get_drvdata(x) #define to_acpi_battery(x) power_supply_get_drvdata(x)
@ -462,12 +461,18 @@ static ssize_t acpi_battery_alarm_store(struct device *dev,
return count; return count;
} }
static const struct device_attribute alarm_attr = { static struct device_attribute alarm_attr = {
.attr = {.name = "alarm", .mode = 0644}, .attr = {.name = "alarm", .mode = 0644},
.show = acpi_battery_alarm_show, .show = acpi_battery_alarm_show,
.store = acpi_battery_alarm_store, .store = acpi_battery_alarm_store,
}; };
static struct attribute *acpi_battery_attrs[] = {
&alarm_attr.attr,
NULL
};
ATTRIBUTE_GROUPS(acpi_battery);
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
Driver Interface Driver Interface
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
@ -509,7 +514,10 @@ static int acpi_battery_read(struct acpi_battery *battery)
static int acpi_battery_add(struct acpi_sbs *sbs, int id) static int acpi_battery_add(struct acpi_sbs *sbs, int id)
{ {
struct acpi_battery *battery = &sbs->battery[id]; struct acpi_battery *battery = &sbs->battery[id];
struct power_supply_config psy_cfg = { .drv_data = battery, }; struct power_supply_config psy_cfg = {
.drv_data = battery,
.attr_grp = acpi_battery_groups,
};
int result; int result;
battery->id = id; battery->id = id;
@ -539,10 +547,6 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
goto end; goto end;
} }
result = device_create_file(&battery->bat->dev, &alarm_attr);
if (result)
goto end;
battery->have_sysfs_alarm = 1;
end: end:
printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n", printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n",
ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
@ -554,11 +558,8 @@ static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
{ {
struct acpi_battery *battery = &sbs->battery[id]; struct acpi_battery *battery = &sbs->battery[id];
if (battery->bat) { if (battery->bat)
if (battery->have_sysfs_alarm)
device_remove_file(&battery->bat->dev, &alarm_attr);
power_supply_unregister(battery->bat); power_supply_unregister(battery->bat);
}
} }
static int acpi_charger_add(struct acpi_sbs *sbs) static int acpi_charger_add(struct acpi_sbs *sbs)

View File

@ -550,9 +550,7 @@ static bool binder_has_work(struct binder_thread *thread, bool do_proc_work)
static bool binder_available_for_proc_work_ilocked(struct binder_thread *thread) static bool binder_available_for_proc_work_ilocked(struct binder_thread *thread)
{ {
return !thread->transaction_stack && return !thread->transaction_stack &&
binder_worklist_empty_ilocked(&thread->todo) && binder_worklist_empty_ilocked(&thread->todo);
(thread->looper & (BINDER_LOOPER_STATE_ENTERED |
BINDER_LOOPER_STATE_REGISTERED));
} }
static void binder_wakeup_poll_threads_ilocked(struct binder_proc *proc, static void binder_wakeup_poll_threads_ilocked(struct binder_proc *proc,

View File

@ -5366,6 +5366,9 @@ static void ata_host_release(struct kref *kref)
for (i = 0; i < host->n_ports; i++) { for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i]; struct ata_port *ap = host->ports[i];
if (!ap)
continue;
kfree(ap->pmp_link); kfree(ap->pmp_link);
kfree(ap->slave_link); kfree(ap->slave_link);
kfree(ap); kfree(ap);
@ -5426,8 +5429,10 @@ struct ata_host *ata_host_alloc(struct device *dev, int max_ports)
} }
dr = devres_alloc(ata_devres_release, 0, GFP_KERNEL); dr = devres_alloc(ata_devres_release, 0, GFP_KERNEL);
if (!dr) if (!dr) {
kfree(host);
goto err_out; goto err_out;
}
devres_add(dev, dr); devres_add(dev, dr);
dev_set_drvdata(dev, host); dev_set_drvdata(dev, host);

View File

@ -540,7 +540,8 @@ static enum ata_completion_errors pata_macio_qc_prep(struct ata_queued_cmd *qc)
while (sg_len) { while (sg_len) {
/* table overflow should never happen */ /* table overflow should never happen */
BUG_ON (pi++ >= MAX_DCMDS); if (WARN_ON_ONCE(pi >= MAX_DCMDS))
return AC_ERR_SYSTEM;
len = (sg_len < MAX_DBDMA_SEG) ? sg_len : MAX_DBDMA_SEG; len = (sg_len < MAX_DBDMA_SEG) ? sg_len : MAX_DBDMA_SEG;
table->command = cpu_to_le16(write ? OUTPUT_MORE: INPUT_MORE); table->command = cpu_to_le16(write ? OUTPUT_MORE: INPUT_MORE);
@ -552,11 +553,13 @@ static enum ata_completion_errors pata_macio_qc_prep(struct ata_queued_cmd *qc)
addr += len; addr += len;
sg_len -= len; sg_len -= len;
++table; ++table;
++pi;
} }
} }
/* Should never happen according to Tejun */ /* Should never happen according to Tejun */
BUG_ON(!pi); if (WARN_ON_ONCE(!pi))
return AC_ERR_SYSTEM;
/* Convert the last command to an input/output */ /* Convert the last command to an input/output */
table--; table--;

View File

@ -1118,8 +1118,8 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe)
rpp->len += skb->len; rpp->len += skb->len;
if (stat & SAR_RSQE_EPDU) { if (stat & SAR_RSQE_EPDU) {
unsigned int len, truesize;
unsigned char *l1l2; unsigned char *l1l2;
unsigned int len;
l1l2 = (unsigned char *) ((unsigned long) skb->data + skb->len - 6); l1l2 = (unsigned char *) ((unsigned long) skb->data + skb->len - 6);
@ -1189,14 +1189,15 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe)
ATM_SKB(skb)->vcc = vcc; ATM_SKB(skb)->vcc = vcc;
__net_timestamp(skb); __net_timestamp(skb);
truesize = skb->truesize;
vcc->push(vcc, skb); vcc->push(vcc, skb);
atomic_inc(&vcc->stats->rx); atomic_inc(&vcc->stats->rx);
if (skb->truesize > SAR_FB_SIZE_3) if (truesize > SAR_FB_SIZE_3)
add_rx_skb(card, 3, SAR_FB_SIZE_3, 1); add_rx_skb(card, 3, SAR_FB_SIZE_3, 1);
else if (skb->truesize > SAR_FB_SIZE_2) else if (truesize > SAR_FB_SIZE_2)
add_rx_skb(card, 2, SAR_FB_SIZE_2, 1); add_rx_skb(card, 2, SAR_FB_SIZE_2, 1);
else if (skb->truesize > SAR_FB_SIZE_1) else if (truesize > SAR_FB_SIZE_1)
add_rx_skb(card, 1, SAR_FB_SIZE_1, 1); add_rx_skb(card, 1, SAR_FB_SIZE_1, 1);
else else
add_rx_skb(card, 0, SAR_FB_SIZE_0, 1); add_rx_skb(card, 0, SAR_FB_SIZE_0, 1);

View File

@ -25,6 +25,7 @@
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/rcupdate.h>
#include <linux/sched/signal.h> #include <linux/sched/signal.h>
#include <linux/sched/mm.h> #include <linux/sched/mm.h>
#include <linux/sysfs.h> #include <linux/sysfs.h>
@ -2194,6 +2195,7 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj,
struct kobj_uevent_env *env) struct kobj_uevent_env *env)
{ {
struct device *dev = kobj_to_dev(kobj); struct device *dev = kobj_to_dev(kobj);
struct device_driver *driver;
int retval = 0; int retval = 0;
/* add device node properties if present */ /* add device node properties if present */
@ -2222,8 +2224,12 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj,
if (dev->type && dev->type->name) if (dev->type && dev->type->name)
add_uevent_var(env, "DEVTYPE=%s", dev->type->name); add_uevent_var(env, "DEVTYPE=%s", dev->type->name);
if (dev->driver) /* Synchronize with module_remove_driver() */
add_uevent_var(env, "DRIVER=%s", dev->driver->name); rcu_read_lock();
driver = READ_ONCE(dev->driver);
if (driver)
add_uevent_var(env, "DRIVER=%s", driver->name);
rcu_read_unlock();
/* Add common DT information about the device */ /* Add common DT information about the device */
of_device_uevent(dev, env); of_device_uevent(dev, env);
@ -2293,11 +2299,8 @@ static ssize_t uevent_show(struct device *dev, struct device_attribute *attr,
if (!env) if (!env)
return -ENOMEM; return -ENOMEM;
/* Synchronize with really_probe() */
device_lock(dev);
/* let the kset specific function add its keys */ /* let the kset specific function add its keys */
retval = kset->uevent_ops->uevent(kset, &dev->kobj, env); retval = kset->uevent_ops->uevent(kset, &dev->kobj, env);
device_unlock(dev);
if (retval) if (retval)
goto out; goto out;

View File

@ -577,6 +577,7 @@ void * devres_open_group(struct device *dev, void *id, gfp_t gfp)
grp->id = grp; grp->id = grp;
if (id) if (id)
grp->id = id; grp->id = id;
grp->color = 0;
spin_lock_irqsave(&dev->devres_lock, flags); spin_lock_irqsave(&dev->devres_lock, flags);
add_dr(dev, &grp->node[0]); add_dr(dev, &grp->node[0]);
@ -901,9 +902,12 @@ void *devm_krealloc(struct device *dev, void *ptr, size_t new_size, gfp_t gfp)
/* /*
* Otherwise: allocate new, larger chunk. We need to allocate before * Otherwise: allocate new, larger chunk. We need to allocate before
* taking the lock as most probably the caller uses GFP_KERNEL. * taking the lock as most probably the caller uses GFP_KERNEL.
* alloc_dr() will call check_dr_size() to reserve extra memory
* for struct devres automatically, so size @new_size user request
* is delivered to it directly as devm_kmalloc() does.
*/ */
new_dr = alloc_dr(devm_kmalloc_release, new_dr = alloc_dr(devm_kmalloc_release,
total_new_size, gfp, dev_to_node(dev)); new_size, gfp, dev_to_node(dev));
if (!new_dr) if (!new_dr)
return NULL; return NULL;
@ -1227,7 +1231,11 @@ EXPORT_SYMBOL_GPL(__devm_alloc_percpu);
*/ */
void devm_free_percpu(struct device *dev, void __percpu *pdata) void devm_free_percpu(struct device *dev, void __percpu *pdata)
{ {
WARN_ON(devres_destroy(dev, devm_percpu_release, devm_percpu_match, /*
(void *)pdata)); * Use devres_release() to prevent memory leakage as
* devm_free_pages() does.
*/
WARN_ON(devres_release(dev, devm_percpu_release, devm_percpu_match,
(__force void *)pdata));
} }
EXPORT_SYMBOL_GPL(devm_free_percpu); EXPORT_SYMBOL_GPL(devm_free_percpu);

View File

@ -7,6 +7,7 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/rcupdate.h>
#include "base.h" #include "base.h"
static char *make_driver_name(struct device_driver *drv) static char *make_driver_name(struct device_driver *drv)
@ -77,6 +78,9 @@ void module_remove_driver(struct device_driver *drv)
if (!drv) if (!drv)
return; return;
/* Synchronize with dev_uevent() */
synchronize_rcu();
sysfs_remove_link(&drv->p->kobj, "module"); sysfs_remove_link(&drv->p->kobj, "module");
if (drv->owner) if (drv->owner)

View File

@ -362,7 +362,7 @@ enum rbd_watch_state {
enum rbd_lock_state { enum rbd_lock_state {
RBD_LOCK_STATE_UNLOCKED, RBD_LOCK_STATE_UNLOCKED,
RBD_LOCK_STATE_LOCKED, RBD_LOCK_STATE_LOCKED,
RBD_LOCK_STATE_RELEASING, RBD_LOCK_STATE_QUIESCING,
}; };
/* WatchNotify::ClientId */ /* WatchNotify::ClientId */
@ -422,7 +422,7 @@ struct rbd_device {
struct list_head running_list; struct list_head running_list;
struct completion acquire_wait; struct completion acquire_wait;
int acquire_err; int acquire_err;
struct completion releasing_wait; struct completion quiescing_wait;
spinlock_t object_map_lock; spinlock_t object_map_lock;
u8 *object_map; u8 *object_map;
@ -525,7 +525,7 @@ static bool __rbd_is_lock_owner(struct rbd_device *rbd_dev)
lockdep_assert_held(&rbd_dev->lock_rwsem); lockdep_assert_held(&rbd_dev->lock_rwsem);
return rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED || return rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED ||
rbd_dev->lock_state == RBD_LOCK_STATE_RELEASING; rbd_dev->lock_state == RBD_LOCK_STATE_QUIESCING;
} }
static bool rbd_is_lock_owner(struct rbd_device *rbd_dev) static bool rbd_is_lock_owner(struct rbd_device *rbd_dev)
@ -3522,13 +3522,14 @@ static void rbd_lock_del_request(struct rbd_img_request *img_req)
lockdep_assert_held(&rbd_dev->lock_rwsem); lockdep_assert_held(&rbd_dev->lock_rwsem);
spin_lock(&rbd_dev->lock_lists_lock); spin_lock(&rbd_dev->lock_lists_lock);
if (!list_empty(&img_req->lock_item)) { if (!list_empty(&img_req->lock_item)) {
rbd_assert(!list_empty(&rbd_dev->running_list));
list_del_init(&img_req->lock_item); list_del_init(&img_req->lock_item);
need_wakeup = (rbd_dev->lock_state == RBD_LOCK_STATE_RELEASING && need_wakeup = (rbd_dev->lock_state == RBD_LOCK_STATE_QUIESCING &&
list_empty(&rbd_dev->running_list)); list_empty(&rbd_dev->running_list));
} }
spin_unlock(&rbd_dev->lock_lists_lock); spin_unlock(&rbd_dev->lock_lists_lock);
if (need_wakeup) if (need_wakeup)
complete(&rbd_dev->releasing_wait); complete(&rbd_dev->quiescing_wait);
} }
static int rbd_img_exclusive_lock(struct rbd_img_request *img_req) static int rbd_img_exclusive_lock(struct rbd_img_request *img_req)
@ -3541,11 +3542,6 @@ static int rbd_img_exclusive_lock(struct rbd_img_request *img_req)
if (rbd_lock_add_request(img_req)) if (rbd_lock_add_request(img_req))
return 1; return 1;
if (rbd_dev->opts->exclusive) {
WARN_ON(1); /* lock got released? */
return -EROFS;
}
/* /*
* Note the use of mod_delayed_work() in rbd_acquire_lock() * Note the use of mod_delayed_work() in rbd_acquire_lock()
* and cancel_delayed_work() in wake_lock_waiters(). * and cancel_delayed_work() in wake_lock_waiters().
@ -4237,16 +4233,16 @@ static bool rbd_quiesce_lock(struct rbd_device *rbd_dev)
/* /*
* Ensure that all in-flight IO is flushed. * Ensure that all in-flight IO is flushed.
*/ */
rbd_dev->lock_state = RBD_LOCK_STATE_RELEASING; rbd_dev->lock_state = RBD_LOCK_STATE_QUIESCING;
rbd_assert(!completion_done(&rbd_dev->releasing_wait)); rbd_assert(!completion_done(&rbd_dev->quiescing_wait));
if (list_empty(&rbd_dev->running_list)) if (list_empty(&rbd_dev->running_list))
return true; return true;
up_write(&rbd_dev->lock_rwsem); up_write(&rbd_dev->lock_rwsem);
wait_for_completion(&rbd_dev->releasing_wait); wait_for_completion(&rbd_dev->quiescing_wait);
down_write(&rbd_dev->lock_rwsem); down_write(&rbd_dev->lock_rwsem);
if (rbd_dev->lock_state != RBD_LOCK_STATE_RELEASING) if (rbd_dev->lock_state != RBD_LOCK_STATE_QUIESCING)
return false; return false;
rbd_assert(list_empty(&rbd_dev->running_list)); rbd_assert(list_empty(&rbd_dev->running_list));
@ -4657,6 +4653,10 @@ static void rbd_reacquire_lock(struct rbd_device *rbd_dev)
rbd_warn(rbd_dev, "failed to update lock cookie: %d", rbd_warn(rbd_dev, "failed to update lock cookie: %d",
ret); ret);
if (rbd_dev->opts->exclusive)
rbd_warn(rbd_dev,
"temporarily releasing lock on exclusive mapping");
/* /*
* Lock cookie cannot be updated on older OSDs, so do * Lock cookie cannot be updated on older OSDs, so do
* a manual release and queue an acquire. * a manual release and queue an acquire.
@ -5455,7 +5455,7 @@ static struct rbd_device *__rbd_dev_create(struct rbd_spec *spec)
INIT_LIST_HEAD(&rbd_dev->acquiring_list); INIT_LIST_HEAD(&rbd_dev->acquiring_list);
INIT_LIST_HEAD(&rbd_dev->running_list); INIT_LIST_HEAD(&rbd_dev->running_list);
init_completion(&rbd_dev->acquire_wait); init_completion(&rbd_dev->acquire_wait);
init_completion(&rbd_dev->releasing_wait); init_completion(&rbd_dev->quiescing_wait);
spin_lock_init(&rbd_dev->object_map_lock); spin_lock_init(&rbd_dev->object_map_lock);
@ -6660,11 +6660,6 @@ static int rbd_add_acquire_lock(struct rbd_device *rbd_dev)
if (ret) if (ret)
return ret; return ret;
/*
* The lock may have been released by now, unless automatic lock
* transitions are disabled.
*/
rbd_assert(!rbd_dev->opts->exclusive || rbd_is_lock_owner(rbd_dev));
return 0; return 0;
} }

View File

@ -428,6 +428,10 @@ static const struct usb_device_id blacklist_table[] = {
BTUSB_WIDEBAND_SPEECH }, BTUSB_WIDEBAND_SPEECH },
{ USB_DEVICE(0x13d3, 0x3571), .driver_info = BTUSB_REALTEK | { USB_DEVICE(0x13d3, 0x3571), .driver_info = BTUSB_REALTEK |
BTUSB_WIDEBAND_SPEECH }, BTUSB_WIDEBAND_SPEECH },
{ USB_DEVICE(0x13d3, 0x3591), .driver_info = BTUSB_REALTEK |
BTUSB_WIDEBAND_SPEECH },
{ USB_DEVICE(0x0489, 0xe125), .driver_info = BTUSB_REALTEK |
BTUSB_WIDEBAND_SPEECH },
/* Realtek Bluetooth devices */ /* Realtek Bluetooth devices */
{ USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01), { USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01),

View File

@ -768,7 +768,8 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file *file,
break; break;
case HCIUARTGETPROTO: case HCIUARTGETPROTO:
if (test_bit(HCI_UART_PROTO_SET, &hu->flags)) if (test_bit(HCI_UART_PROTO_SET, &hu->flags) &&
test_bit(HCI_UART_PROTO_READY, &hu->flags))
err = hu->proto->id; err = hu->proto->id;
else else
err = -EUNATCH; err = -EUNATCH;

View File

@ -142,8 +142,10 @@ static int __init mod_init(void)
found: found:
err = pci_read_config_dword(pdev, 0x58, &pmbase); err = pci_read_config_dword(pdev, 0x58, &pmbase);
if (err) if (err) {
err = pcibios_err_to_errno(err);
goto put_dev; goto put_dev;
}
pmbase &= 0x0000FF00; pmbase &= 0x0000FF00;
if (pmbase == 0) { if (pmbase == 0) {

View File

@ -47,6 +47,8 @@ static int tpm_bios_measurements_open(struct inode *inode,
if (!err) { if (!err) {
seq = file->private_data; seq = file->private_data;
seq->private = chip; seq->private = chip;
} else {
put_device(&chip->dev);
} }
return err; return err;

View File

@ -505,7 +505,7 @@ da8xx_cfgchip_register_usb0_clk48(struct device *dev,
const char * const parent_names[] = { "usb_refclkin", "pll0_auxclk" }; const char * const parent_names[] = { "usb_refclkin", "pll0_auxclk" };
struct clk *fck_clk; struct clk *fck_clk;
struct da8xx_usb0_clk48 *usb0; struct da8xx_usb0_clk48 *usb0;
struct clk_init_data init; struct clk_init_data init = {};
int ret; int ret;
fck_clk = devm_clk_get(dev, "fck"); fck_clk = devm_clk_get(dev, "fck");
@ -580,7 +580,7 @@ da8xx_cfgchip_register_usb1_clk48(struct device *dev,
{ {
const char * const parent_names[] = { "usb0_clk48", "usb_refclkin" }; const char * const parent_names[] = { "usb0_clk48", "usb_refclkin" };
struct da8xx_usb1_clk48 *usb1; struct da8xx_usb1_clk48 *usb1;
struct clk_init_data init; struct clk_init_data init = {};
int ret; int ret;
usb1 = devm_kzalloc(dev, sizeof(*usb1), GFP_KERNEL); usb1 = devm_kzalloc(dev, sizeof(*usb1), GFP_KERNEL);

View File

@ -530,6 +530,7 @@ static void sh_cmt_set_next(struct sh_cmt_channel *ch, unsigned long delta)
static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id) static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
{ {
struct sh_cmt_channel *ch = dev_id; struct sh_cmt_channel *ch = dev_id;
unsigned long flags;
/* clear flags */ /* clear flags */
sh_cmt_write_cmcsr(ch, sh_cmt_read_cmcsr(ch) & sh_cmt_write_cmcsr(ch, sh_cmt_read_cmcsr(ch) &
@ -560,6 +561,8 @@ static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
ch->flags &= ~FLAG_SKIPEVENT; ch->flags &= ~FLAG_SKIPEVENT;
raw_spin_lock_irqsave(&ch->lock, flags);
if (ch->flags & FLAG_REPROGRAM) { if (ch->flags & FLAG_REPROGRAM) {
ch->flags &= ~FLAG_REPROGRAM; ch->flags &= ~FLAG_REPROGRAM;
sh_cmt_clock_event_program_verify(ch, 1); sh_cmt_clock_event_program_verify(ch, 1);
@ -572,6 +575,8 @@ static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
ch->flags &= ~FLAG_IRQCONTEXT; ch->flags &= ~FLAG_IRQCONTEXT;
raw_spin_unlock_irqrestore(&ch->lock, flags);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
@ -770,12 +775,18 @@ static int sh_cmt_clock_event_next(unsigned long delta,
struct clock_event_device *ced) struct clock_event_device *ced)
{ {
struct sh_cmt_channel *ch = ced_to_sh_cmt(ced); struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
unsigned long flags;
BUG_ON(!clockevent_state_oneshot(ced)); BUG_ON(!clockevent_state_oneshot(ced));
raw_spin_lock_irqsave(&ch->lock, flags);
if (likely(ch->flags & FLAG_IRQCONTEXT)) if (likely(ch->flags & FLAG_IRQCONTEXT))
ch->next_match_value = delta - 1; ch->next_match_value = delta - 1;
else else
sh_cmt_set_next(ch, delta - 1); __sh_cmt_set_next(ch, delta - 1);
raw_spin_unlock_irqrestore(&ch->lock, flags);
return 0; return 0;
} }

View File

@ -83,20 +83,28 @@ static u64 notrace tpm_read_sched_clock(void)
static int tpm_set_next_event(unsigned long delta, static int tpm_set_next_event(unsigned long delta,
struct clock_event_device *evt) struct clock_event_device *evt)
{ {
unsigned long next, now; unsigned long next, prev, now;
next = tpm_read_counter(); prev = tpm_read_counter();
next += delta; next = prev + delta;
writel(next, timer_base + TPM_C0V); writel(next, timer_base + TPM_C0V);
now = tpm_read_counter(); now = tpm_read_counter();
/*
* Need to wait CNT increase at least 1 cycle to make sure
* the C0V has been updated into HW.
*/
if ((next & 0xffffffff) != readl(timer_base + TPM_C0V))
while (now == tpm_read_counter())
;
/* /*
* NOTE: We observed in a very small probability, the bus fabric * NOTE: We observed in a very small probability, the bus fabric
* contention between GPU and A7 may results a few cycles delay * contention between GPU and A7 may results a few cycles delay
* of writing CNT registers which may cause the min_delta event got * of writing CNT registers which may cause the min_delta event got
* missed, so we need add a ETIME check here in case it happened. * missed, so we need add a ETIME check here in case it happened.
*/ */
return (int)(next - now) <= 0 ? -ETIME : 0; return (now - prev) >= delta ? -ETIME : 0;
} }
static int tpm_set_state_oneshot(struct clock_event_device *evt) static int tpm_set_state_oneshot(struct clock_event_device *evt)

View File

@ -167,7 +167,7 @@ static vm_fault_t cma_heap_vm_fault(struct vm_fault *vmf)
struct vm_area_struct *vma = vmf->vma; struct vm_area_struct *vma = vmf->vma;
struct cma_heap_buffer *buffer = vma->vm_private_data; struct cma_heap_buffer *buffer = vma->vm_private_data;
if (vmf->pgoff > buffer->pagecount) if (vmf->pgoff >= buffer->pagecount)
return VM_FAULT_SIGBUS; return VM_FAULT_SIGBUS;
vmf->page = buffer->pages[vmf->pgoff]; vmf->page = buffer->pages[vmf->pgoff];

View File

@ -16,6 +16,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/log2.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
@ -624,12 +625,10 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
struct dw_desc *prev; struct dw_desc *prev;
struct dw_desc *first; struct dw_desc *first;
u32 ctllo, ctlhi; u32 ctllo, ctlhi;
u8 m_master = dwc->dws.m_master; u8 lms = DWC_LLP_LMS(dwc->dws.m_master);
u8 lms = DWC_LLP_LMS(m_master);
dma_addr_t reg; dma_addr_t reg;
unsigned int reg_width; unsigned int reg_width;
unsigned int mem_width; unsigned int mem_width;
unsigned int data_width = dw->pdata->data_width[m_master];
unsigned int i; unsigned int i;
struct scatterlist *sg; struct scatterlist *sg;
size_t total_len = 0; size_t total_len = 0;
@ -663,7 +662,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
mem = sg_dma_address(sg); mem = sg_dma_address(sg);
len = sg_dma_len(sg); len = sg_dma_len(sg);
mem_width = __ffs(data_width | mem | len); mem_width = __ffs(sconfig->src_addr_width | mem | len);
slave_sg_todev_fill_desc: slave_sg_todev_fill_desc:
desc = dwc_desc_get(dwc); desc = dwc_desc_get(dwc);
@ -723,7 +722,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
lli_write(desc, sar, reg); lli_write(desc, sar, reg);
lli_write(desc, dar, mem); lli_write(desc, dar, mem);
lli_write(desc, ctlhi, ctlhi); lli_write(desc, ctlhi, ctlhi);
mem_width = __ffs(data_width | mem); mem_width = __ffs(sconfig->dst_addr_width | mem);
lli_write(desc, ctllo, ctllo | DWC_CTLL_DST_WIDTH(mem_width)); lli_write(desc, ctllo, ctllo | DWC_CTLL_DST_WIDTH(mem_width));
desc->len = dlen; desc->len = dlen;
@ -783,17 +782,93 @@ bool dw_dma_filter(struct dma_chan *chan, void *param)
} }
EXPORT_SYMBOL_GPL(dw_dma_filter); EXPORT_SYMBOL_GPL(dw_dma_filter);
static int dwc_verify_p_buswidth(struct dma_chan *chan)
{
struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
struct dw_dma *dw = to_dw_dma(chan->device);
u32 reg_width, max_width;
if (dwc->dma_sconfig.direction == DMA_MEM_TO_DEV)
reg_width = dwc->dma_sconfig.dst_addr_width;
else if (dwc->dma_sconfig.direction == DMA_DEV_TO_MEM)
reg_width = dwc->dma_sconfig.src_addr_width;
else /* DMA_MEM_TO_MEM */
return 0;
max_width = dw->pdata->data_width[dwc->dws.p_master];
/* Fall-back to 1-byte transfer width if undefined */
if (reg_width == DMA_SLAVE_BUSWIDTH_UNDEFINED)
reg_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
else if (!is_power_of_2(reg_width) || reg_width > max_width)
return -EINVAL;
else /* bus width is valid */
return 0;
/* Update undefined addr width value */
if (dwc->dma_sconfig.direction == DMA_MEM_TO_DEV)
dwc->dma_sconfig.dst_addr_width = reg_width;
else /* DMA_DEV_TO_MEM */
dwc->dma_sconfig.src_addr_width = reg_width;
return 0;
}
static int dwc_verify_m_buswidth(struct dma_chan *chan)
{
struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
struct dw_dma *dw = to_dw_dma(chan->device);
u32 reg_width, reg_burst, mem_width;
mem_width = dw->pdata->data_width[dwc->dws.m_master];
/*
* It's possible to have a data portion locked in the DMA FIFO in case
* of the channel suspension. Subsequent channel disabling will cause
* that data silent loss. In order to prevent that maintain the src and
* dst transfer widths coherency by means of the relation:
* (CTLx.SRC_TR_WIDTH * CTLx.SRC_MSIZE >= CTLx.DST_TR_WIDTH)
* Look for the details in the commit message that brings this change.
*
* Note the DMA configs utilized in the calculations below must have
* been verified to have correct values by this method call.
*/
if (dwc->dma_sconfig.direction == DMA_MEM_TO_DEV) {
reg_width = dwc->dma_sconfig.dst_addr_width;
if (mem_width < reg_width)
return -EINVAL;
dwc->dma_sconfig.src_addr_width = mem_width;
} else if (dwc->dma_sconfig.direction == DMA_DEV_TO_MEM) {
reg_width = dwc->dma_sconfig.src_addr_width;
reg_burst = rounddown_pow_of_two(dwc->dma_sconfig.src_maxburst);
dwc->dma_sconfig.dst_addr_width = min(mem_width, reg_width * reg_burst);
}
return 0;
}
static int dwc_config(struct dma_chan *chan, struct dma_slave_config *sconfig) static int dwc_config(struct dma_chan *chan, struct dma_slave_config *sconfig)
{ {
struct dw_dma_chan *dwc = to_dw_dma_chan(chan); struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
struct dw_dma *dw = to_dw_dma(chan->device); struct dw_dma *dw = to_dw_dma(chan->device);
int ret;
memcpy(&dwc->dma_sconfig, sconfig, sizeof(*sconfig)); memcpy(&dwc->dma_sconfig, sconfig, sizeof(*sconfig));
dwc->dma_sconfig.src_maxburst = dwc->dma_sconfig.src_maxburst =
clamp(dwc->dma_sconfig.src_maxburst, 0U, dwc->max_burst); clamp(dwc->dma_sconfig.src_maxburst, 1U, dwc->max_burst);
dwc->dma_sconfig.dst_maxburst = dwc->dma_sconfig.dst_maxburst =
clamp(dwc->dma_sconfig.dst_maxburst, 0U, dwc->max_burst); clamp(dwc->dma_sconfig.dst_maxburst, 1U, dwc->max_burst);
ret = dwc_verify_p_buswidth(chan);
if (ret)
return ret;
ret = dwc_verify_m_buswidth(chan);
if (ret)
return ret;
dw->encode_maxburst(dwc, &dwc->dma_sconfig.src_maxburst); dw->encode_maxburst(dwc, &dwc->dma_sconfig.src_maxburst);
dw->encode_maxburst(dwc, &dwc->dma_sconfig.dst_maxburst); dw->encode_maxburst(dwc, &dwc->dma_sconfig.dst_maxburst);

View File

@ -58,11 +58,13 @@ obj-$(CONFIG_EDAC_MPC85XX) += mpc85xx_edac_mod.o
layerscape_edac_mod-y := fsl_ddr_edac.o layerscape_edac.o layerscape_edac_mod-y := fsl_ddr_edac.o layerscape_edac.o
obj-$(CONFIG_EDAC_LAYERSCAPE) += layerscape_edac_mod.o obj-$(CONFIG_EDAC_LAYERSCAPE) += layerscape_edac_mod.o
skx_edac-y := skx_common.o skx_base.o skx_edac_common-y := skx_common.o
obj-$(CONFIG_EDAC_SKX) += skx_edac.o
i10nm_edac-y := skx_common.o i10nm_base.o skx_edac-y := skx_base.o
obj-$(CONFIG_EDAC_I10NM) += i10nm_edac.o obj-$(CONFIG_EDAC_SKX) += skx_edac.o skx_edac_common.o
i10nm_edac-y := i10nm_base.o
obj-$(CONFIG_EDAC_I10NM) += i10nm_edac.o skx_edac_common.o
obj-$(CONFIG_EDAC_MV64X60) += mv64x60_edac.o obj-$(CONFIG_EDAC_MV64X60) += mv64x60_edac.o
obj-$(CONFIG_EDAC_CELL) += cell_edac.o obj-$(CONFIG_EDAC_CELL) += cell_edac.o

View File

@ -23,10 +23,13 @@
#include "skx_common.h" #include "skx_common.h"
static const char * const component_names[] = { static const char * const component_names[] = {
[INDEX_SOCKET] = "ProcessorSocketId", [INDEX_SOCKET] = "ProcessorSocketId",
[INDEX_MEMCTRL] = "MemoryControllerId", [INDEX_MEMCTRL] = "MemoryControllerId",
[INDEX_CHANNEL] = "ChannelId", [INDEX_CHANNEL] = "ChannelId",
[INDEX_DIMM] = "DimmSlotId", [INDEX_DIMM] = "DimmSlotId",
[INDEX_NM_MEMCTRL] = "NmMemoryControllerId",
[INDEX_NM_CHANNEL] = "NmChannelId",
[INDEX_NM_DIMM] = "NmDimmSlotId",
}; };
static int component_indices[ARRAY_SIZE(component_names)]; static int component_indices[ARRAY_SIZE(component_names)];
@ -34,14 +37,16 @@ static int adxl_component_count;
static const char * const *adxl_component_names; static const char * const *adxl_component_names;
static u64 *adxl_values; static u64 *adxl_values;
static char *adxl_msg; static char *adxl_msg;
static unsigned long adxl_nm_bitmap;
static char skx_msg[MSG_SIZE]; static char skx_msg[MSG_SIZE];
static skx_decode_f skx_decode; static skx_decode_f skx_decode;
static skx_show_retry_log_f skx_show_retry_rd_err_log; static skx_show_retry_log_f skx_show_retry_rd_err_log;
static u64 skx_tolm, skx_tohm; static u64 skx_tolm, skx_tohm;
static LIST_HEAD(dev_edac_list); static LIST_HEAD(dev_edac_list);
static bool skx_mem_cfg_2lm;
int __init skx_adxl_get(void) int skx_adxl_get(void)
{ {
const char * const *names; const char * const *names;
int i, j; int i, j;
@ -56,14 +61,25 @@ int __init skx_adxl_get(void)
for (j = 0; names[j]; j++) { for (j = 0; names[j]; j++) {
if (!strcmp(component_names[i], names[j])) { if (!strcmp(component_names[i], names[j])) {
component_indices[i] = j; component_indices[i] = j;
if (i >= INDEX_NM_FIRST)
adxl_nm_bitmap |= 1 << i;
break; break;
} }
} }
if (!names[j]) if (!names[j] && i < INDEX_NM_FIRST)
goto err; goto err;
} }
if (skx_mem_cfg_2lm) {
if (!adxl_nm_bitmap)
skx_printk(KERN_NOTICE, "Not enough ADXL components for 2-level memory.\n");
else
edac_dbg(2, "adxl_nm_bitmap: 0x%lx\n", adxl_nm_bitmap);
}
adxl_component_names = names; adxl_component_names = names;
while (*names++) while (*names++)
adxl_component_count++; adxl_component_count++;
@ -92,14 +108,16 @@ int __init skx_adxl_get(void)
return -ENODEV; return -ENODEV;
} }
EXPORT_SYMBOL_GPL(skx_adxl_get);
void __exit skx_adxl_put(void) void skx_adxl_put(void)
{ {
kfree(adxl_values); kfree(adxl_values);
kfree(adxl_msg); kfree(adxl_msg);
} }
EXPORT_SYMBOL_GPL(skx_adxl_put);
static bool skx_adxl_decode(struct decoded_addr *res) static bool skx_adxl_decode(struct decoded_addr *res, bool error_in_1st_level_mem)
{ {
struct skx_dev *d; struct skx_dev *d;
int i, len = 0; int i, len = 0;
@ -116,11 +134,20 @@ static bool skx_adxl_decode(struct decoded_addr *res)
} }
res->socket = (int)adxl_values[component_indices[INDEX_SOCKET]]; res->socket = (int)adxl_values[component_indices[INDEX_SOCKET]];
res->imc = (int)adxl_values[component_indices[INDEX_MEMCTRL]]; if (error_in_1st_level_mem) {
res->channel = (int)adxl_values[component_indices[INDEX_CHANNEL]]; res->imc = (adxl_nm_bitmap & BIT_NM_MEMCTRL) ?
res->dimm = (int)adxl_values[component_indices[INDEX_DIMM]]; (int)adxl_values[component_indices[INDEX_NM_MEMCTRL]] : -1;
res->channel = (adxl_nm_bitmap & BIT_NM_CHANNEL) ?
(int)adxl_values[component_indices[INDEX_NM_CHANNEL]] : -1;
res->dimm = (adxl_nm_bitmap & BIT_NM_DIMM) ?
(int)adxl_values[component_indices[INDEX_NM_DIMM]] : -1;
} else {
res->imc = (int)adxl_values[component_indices[INDEX_MEMCTRL]];
res->channel = (int)adxl_values[component_indices[INDEX_CHANNEL]];
res->dimm = (int)adxl_values[component_indices[INDEX_DIMM]];
}
if (res->imc > NUM_IMC - 1) { if (res->imc > NUM_IMC - 1 || res->imc < 0) {
skx_printk(KERN_ERR, "Bad imc %d\n", res->imc); skx_printk(KERN_ERR, "Bad imc %d\n", res->imc);
return false; return false;
} }
@ -151,11 +178,18 @@ static bool skx_adxl_decode(struct decoded_addr *res)
return true; return true;
} }
void skx_set_mem_cfg(bool mem_cfg_2lm)
{
skx_mem_cfg_2lm = mem_cfg_2lm;
}
EXPORT_SYMBOL_GPL(skx_set_mem_cfg);
void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log) void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log)
{ {
skx_decode = decode; skx_decode = decode;
skx_show_retry_rd_err_log = show_retry_log; skx_show_retry_rd_err_log = show_retry_log;
} }
EXPORT_SYMBOL_GPL(skx_set_decode);
int skx_get_src_id(struct skx_dev *d, int off, u8 *id) int skx_get_src_id(struct skx_dev *d, int off, u8 *id)
{ {
@ -169,6 +203,7 @@ int skx_get_src_id(struct skx_dev *d, int off, u8 *id)
*id = GET_BITFIELD(reg, 12, 14); *id = GET_BITFIELD(reg, 12, 14);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(skx_get_src_id);
int skx_get_node_id(struct skx_dev *d, u8 *id) int skx_get_node_id(struct skx_dev *d, u8 *id)
{ {
@ -182,6 +217,7 @@ int skx_get_node_id(struct skx_dev *d, u8 *id)
*id = GET_BITFIELD(reg, 0, 2); *id = GET_BITFIELD(reg, 0, 2);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(skx_get_node_id);
static int get_width(u32 mtr) static int get_width(u32 mtr)
{ {
@ -247,6 +283,7 @@ int skx_get_all_bus_mappings(struct res_config *cfg, struct list_head **list)
*list = &dev_edac_list; *list = &dev_edac_list;
return ndev; return ndev;
} }
EXPORT_SYMBOL_GPL(skx_get_all_bus_mappings);
int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm) int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm)
{ {
@ -286,6 +323,7 @@ int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm)
pci_dev_put(pdev); pci_dev_put(pdev);
return -ENODEV; return -ENODEV;
} }
EXPORT_SYMBOL_GPL(skx_get_hi_lo);
static int skx_get_dimm_attr(u32 reg, int lobit, int hibit, int add, static int skx_get_dimm_attr(u32 reg, int lobit, int hibit, int add,
int minval, int maxval, const char *name) int minval, int maxval, const char *name)
@ -339,6 +377,7 @@ int skx_get_dimm_info(u32 mtr, u32 mcmtr, u32 amap, struct dimm_info *dimm,
return 1; return 1;
} }
EXPORT_SYMBOL_GPL(skx_get_dimm_info);
int skx_get_nvdimm_info(struct dimm_info *dimm, struct skx_imc *imc, int skx_get_nvdimm_info(struct dimm_info *dimm, struct skx_imc *imc,
int chan, int dimmno, const char *mod_str) int chan, int dimmno, const char *mod_str)
@ -387,6 +426,7 @@ int skx_get_nvdimm_info(struct dimm_info *dimm, struct skx_imc *imc,
return (size == 0 || size == ~0ull) ? 0 : 1; return (size == 0 || size == ~0ull) ? 0 : 1;
} }
EXPORT_SYMBOL_GPL(skx_get_nvdimm_info);
int skx_register_mci(struct skx_imc *imc, struct pci_dev *pdev, int skx_register_mci(struct skx_imc *imc, struct pci_dev *pdev,
const char *ctl_name, const char *mod_str, const char *ctl_name, const char *mod_str,
@ -454,6 +494,7 @@ int skx_register_mci(struct skx_imc *imc, struct pci_dev *pdev,
imc->mci = NULL; imc->mci = NULL;
return rc; return rc;
} }
EXPORT_SYMBOL_GPL(skx_register_mci);
static void skx_unregister_mci(struct skx_imc *imc) static void skx_unregister_mci(struct skx_imc *imc)
{ {
@ -565,6 +606,21 @@ static void skx_mce_output_error(struct mem_ctl_info *mci,
optype, skx_msg); optype, skx_msg);
} }
static bool skx_error_in_1st_level_mem(const struct mce *m)
{
u32 errcode;
if (!skx_mem_cfg_2lm)
return false;
errcode = GET_BITFIELD(m->status, 0, 15);
if ((errcode & 0xef80) != 0x280)
return false;
return true;
}
int skx_mce_check_error(struct notifier_block *nb, unsigned long val, int skx_mce_check_error(struct notifier_block *nb, unsigned long val,
void *data) void *data)
{ {
@ -584,7 +640,7 @@ int skx_mce_check_error(struct notifier_block *nb, unsigned long val,
res.addr = mce->addr; res.addr = mce->addr;
if (adxl_component_count) { if (adxl_component_count) {
if (!skx_adxl_decode(&res)) if (!skx_adxl_decode(&res, skx_error_in_1st_level_mem(mce)))
return NOTIFY_DONE; return NOTIFY_DONE;
} else if (!skx_decode || !skx_decode(&res)) { } else if (!skx_decode || !skx_decode(&res)) {
return NOTIFY_DONE; return NOTIFY_DONE;
@ -618,6 +674,7 @@ int skx_mce_check_error(struct notifier_block *nb, unsigned long val,
mce->kflags |= MCE_HANDLED_EDAC; mce->kflags |= MCE_HANDLED_EDAC;
return NOTIFY_DONE; return NOTIFY_DONE;
} }
EXPORT_SYMBOL_GPL(skx_mce_check_error);
void skx_remove(void) void skx_remove(void)
{ {
@ -653,3 +710,8 @@ void skx_remove(void)
kfree(d); kfree(d);
} }
} }
EXPORT_SYMBOL_GPL(skx_remove);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Tony Luck");
MODULE_DESCRIPTION("MC Driver for Intel server processors");

View File

@ -9,6 +9,8 @@
#ifndef _SKX_COMM_EDAC_H #ifndef _SKX_COMM_EDAC_H
#define _SKX_COMM_EDAC_H #define _SKX_COMM_EDAC_H
#include <linux/bits.h>
#define MSG_SIZE 1024 #define MSG_SIZE 1024
/* /*
@ -90,9 +92,17 @@ enum {
INDEX_MEMCTRL, INDEX_MEMCTRL,
INDEX_CHANNEL, INDEX_CHANNEL,
INDEX_DIMM, INDEX_DIMM,
INDEX_NM_FIRST,
INDEX_NM_MEMCTRL = INDEX_NM_FIRST,
INDEX_NM_CHANNEL,
INDEX_NM_DIMM,
INDEX_MAX INDEX_MAX
}; };
#define BIT_NM_MEMCTRL BIT_ULL(INDEX_NM_MEMCTRL)
#define BIT_NM_CHANNEL BIT_ULL(INDEX_NM_CHANNEL)
#define BIT_NM_DIMM BIT_ULL(INDEX_NM_DIMM)
struct decoded_addr { struct decoded_addr {
struct skx_dev *dev; struct skx_dev *dev;
u64 addr; u64 addr;
@ -124,9 +134,10 @@ typedef int (*get_dimm_config_f)(struct mem_ctl_info *mci);
typedef bool (*skx_decode_f)(struct decoded_addr *res); typedef bool (*skx_decode_f)(struct decoded_addr *res);
typedef void (*skx_show_retry_log_f)(struct decoded_addr *res, char *msg, int len); typedef void (*skx_show_retry_log_f)(struct decoded_addr *res, char *msg, int len);
int __init skx_adxl_get(void); int skx_adxl_get(void);
void __exit skx_adxl_put(void); void skx_adxl_put(void);
void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log); void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log);
void skx_set_mem_cfg(bool mem_cfg_2lm);
int skx_get_src_id(struct skx_dev *d, int off, u8 *id); int skx_get_src_id(struct skx_dev *d, int off, u8 *id);
int skx_get_node_id(struct skx_dev *d, u8 *id); int skx_get_node_id(struct skx_dev *d, u8 *id);

View File

@ -22,12 +22,14 @@
* @chan: Transmit/Receive mailbox channel * @chan: Transmit/Receive mailbox channel
* @cinfo: SCMI channel info * @cinfo: SCMI channel info
* @shmem: Transmit/Receive shared memory area * @shmem: Transmit/Receive shared memory area
* @chan_lock: Lock that prevents multiple xfers from being queued
*/ */
struct scmi_mailbox { struct scmi_mailbox {
struct mbox_client cl; struct mbox_client cl;
struct mbox_chan *chan; struct mbox_chan *chan;
struct scmi_chan_info *cinfo; struct scmi_chan_info *cinfo;
struct scmi_shared_mem __iomem *shmem; struct scmi_shared_mem __iomem *shmem;
struct mutex chan_lock;
}; };
#define client_to_scmi_mailbox(c) container_of(c, struct scmi_mailbox, cl) #define client_to_scmi_mailbox(c) container_of(c, struct scmi_mailbox, cl)
@ -138,6 +140,7 @@ static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
cinfo->transport_info = smbox; cinfo->transport_info = smbox;
smbox->cinfo = cinfo; smbox->cinfo = cinfo;
mutex_init(&smbox->chan_lock);
return 0; return 0;
} }
@ -165,26 +168,33 @@ static int mailbox_send_message(struct scmi_chan_info *cinfo,
struct scmi_mailbox *smbox = cinfo->transport_info; struct scmi_mailbox *smbox = cinfo->transport_info;
int ret; int ret;
/*
* The mailbox layer has its own queue. However the mailbox queue confuses
* the per message SCMI timeouts since the clock starts when the message is
* submitted into the mailbox queue. So when multiple messages are queued up
* the clock starts on all messages instead of only the one inflight.
*/
mutex_lock(&smbox->chan_lock);
ret = mbox_send_message(smbox->chan, xfer); ret = mbox_send_message(smbox->chan, xfer);
/* mbox_send_message returns non-negative value on success, so reset */ /* mbox_send_message returns non-negative value on success, so reset */
if (ret > 0) if (ret < 0) {
ret = 0; mutex_unlock(&smbox->chan_lock);
return ret;
}
return ret; return 0;
} }
static void mailbox_mark_txdone(struct scmi_chan_info *cinfo, int ret) static void mailbox_mark_txdone(struct scmi_chan_info *cinfo, int ret)
{ {
struct scmi_mailbox *smbox = cinfo->transport_info; struct scmi_mailbox *smbox = cinfo->transport_info;
/*
* NOTE: we might prefer not to need the mailbox ticker to manage the
* transfer queueing since the protocol layer queues things by itself.
* Unfortunately, we have to kick the mailbox framework after we have
* received our message.
*/
mbox_client_txdone(smbox->chan, ret); mbox_client_txdone(smbox->chan, ret);
/* Release channel */
mutex_unlock(&smbox->chan_lock);
} }
static void mailbox_fetch_response(struct scmi_chan_info *cinfo, static void mailbox_fetch_response(struct scmi_chan_info *cinfo,

View File

@ -199,9 +199,8 @@ static int mox_get_board_info(struct mox_rwtm *rwtm)
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2); if (!wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2))
if (ret < 0) return -ETIMEDOUT;
return ret;
ret = mox_get_status(MBOX_CMD_BOARD_INFO, reply->retval); ret = mox_get_status(MBOX_CMD_BOARD_INFO, reply->retval);
if (ret == -ENODATA) { if (ret == -ENODATA) {
@ -235,9 +234,8 @@ static int mox_get_board_info(struct mox_rwtm *rwtm)
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2); if (!wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2))
if (ret < 0) return -ETIMEDOUT;
return ret;
ret = mox_get_status(MBOX_CMD_ECDSA_PUB_KEY, reply->retval); ret = mox_get_status(MBOX_CMD_ECDSA_PUB_KEY, reply->retval);
if (ret == -ENODATA) { if (ret == -ENODATA) {
@ -274,9 +272,8 @@ static int check_get_random_support(struct mox_rwtm *rwtm)
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2); if (!wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2))
if (ret < 0) return -ETIMEDOUT;
return ret;
return mox_get_status(MBOX_CMD_GET_RANDOM, rwtm->reply.retval); return mox_get_status(MBOX_CMD_GET_RANDOM, rwtm->reply.retval);
} }
@ -499,6 +496,7 @@ static int turris_mox_rwtm_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, rwtm); platform_set_drvdata(pdev, rwtm);
mutex_init(&rwtm->busy); mutex_init(&rwtm->busy);
init_completion(&rwtm->cmd_done);
rwtm->mbox_client.dev = dev; rwtm->mbox_client.dev = dev;
rwtm->mbox_client.rx_callback = mox_rwtm_rx_callback; rwtm->mbox_client.rx_callback = mox_rwtm_rx_callback;
@ -512,8 +510,6 @@ static int turris_mox_rwtm_probe(struct platform_device *pdev)
goto remove_files; goto remove_files;
} }
init_completion(&rwtm->cmd_done);
ret = mox_get_board_info(rwtm); ret = mox_get_board_info(rwtm);
if (ret < 0) if (ret < 0)
dev_warn(dev, "Cannot read board information: %i\n", ret); dev_warn(dev, "Cannot read board information: %i\n", ret);

View File

@ -100,6 +100,7 @@ struct amdgpu_afmt_acr amdgpu_afmt_acr(uint32_t clock)
amdgpu_afmt_calc_cts(clock, &res.cts_32khz, &res.n_32khz, 32000); amdgpu_afmt_calc_cts(clock, &res.cts_32khz, &res.n_32khz, 32000);
amdgpu_afmt_calc_cts(clock, &res.cts_44_1khz, &res.n_44_1khz, 44100); amdgpu_afmt_calc_cts(clock, &res.cts_44_1khz, &res.n_44_1khz, 44100);
amdgpu_afmt_calc_cts(clock, &res.cts_48khz, &res.n_48khz, 48000); amdgpu_afmt_calc_cts(clock, &res.cts_48khz, &res.n_48khz, 48000);
res.clock = clock;
return res; return res;
} }

View File

@ -1626,6 +1626,8 @@ int amdgpu_atombios_init_mc_reg_table(struct amdgpu_device *adev,
(u32)le32_to_cpu(*((u32 *)reg_data + j)); (u32)le32_to_cpu(*((u32 *)reg_data + j));
j++; j++;
} else if ((reg_table->mc_reg_address[i].pre_reg_data & LOW_NIBBLE_MASK) == DATA_EQU_PREV) { } else if ((reg_table->mc_reg_address[i].pre_reg_data & LOW_NIBBLE_MASK) == DATA_EQU_PREV) {
if (i == 0)
continue;
reg_table->mc_reg_table_entry[num_ranges].mc_data[i] = reg_table->mc_reg_table_entry[num_ranges].mc_data[i] =
reg_table->mc_reg_table_entry[num_ranges].mc_data[i - 1]; reg_table->mc_reg_table_entry[num_ranges].mc_data[i - 1];
} }

View File

@ -213,6 +213,9 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
struct amdgpu_firmware_info *ucode; struct amdgpu_firmware_info *ucode;
id = fw_type_convert(cgs_device, type); id = fw_type_convert(cgs_device, type);
if (id >= AMDGPU_UCODE_ID_MAXIMUM)
return -EINVAL;
ucode = &adev->firmware.ucode[id]; ucode = &adev->firmware.ucode[id];
if (ucode->fw == NULL) if (ucode->fw == NULL)
return -EINVAL; return -EINVAL;

Some files were not shown because too many files have changed in this diff Show More