This is the 6.1.113 stable release

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAmcRD6QACgkQONu9yGCS
 aT6Kjg/5AQ+HmrE8dMEDCOeN2noXxUDMAOUoR9JTc+RGJlVQBf74jITg2yYdGqcC
 gjJz3qIciBLK4DWwmlvFxRtZzUxpQyEz9q+LpOUWOBdzoNNBB+AltbGilxpdEZ3F
 D2nGHLDHLVxRPs11yQMI5DhBd58QTzGroQAr3mbJlwTJuxFMv250Cjq7WBwUyV2r
 2XJjsBxheWkxEkWrEfQ9WbBL50yCQul+9fpDuGe6vA0dEbck3/6YfJ+Q3bjCkhKZ
 n743f2O+ZoPVAw0IGNn0iNNjIaQrugLjthGEC4Dwb/Afvmvz+EitCeJyNsl8XfAz
 bA4McJ1oXoic7W6rbcww6JQgAWhnXzPBL96rYonAKBby1bCXWb11wgDXH06JwI+D
 GWRhp+ny5sZwxN3oWjR5YZPYgsQM4r6I+A2ZhSbx2qKUQkGeZQ145u2rbxcRcp+e
 LqzT0IIxpKWXb46KHutOq1YGg69ms0BsNNhlFcnZI3jdIQefw/1oWpxOqTVJ2rNt
 Jz9HWfC5+sHd3+gbbdfg8rhZstA7xgKkdUPdNV8ntPfLEPOTmlimBs8+GRtxPLgV
 OYoChWrc7UpBc9NDYZKqHH5u7/mXQzt1dOFejVaEk147dUlMAyppjOrcPqxYWvqq
 9/wYGBcW0KjXuazyWDaI6jOwhyEzX3doJCS3sbGfYzsCdqMmdYw=
 =GFiq
 -----END PGP SIGNATURE-----

Merge tag 'v6.1.113' into v6.1/standard/base

This is the 6.1.113 stable release

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAmcRD6QACgkQONu9yGCS
# aT6Kjg/5AQ+HmrE8dMEDCOeN2noXxUDMAOUoR9JTc+RGJlVQBf74jITg2yYdGqcC
# gjJz3qIciBLK4DWwmlvFxRtZzUxpQyEz9q+LpOUWOBdzoNNBB+AltbGilxpdEZ3F
# D2nGHLDHLVxRPs11yQMI5DhBd58QTzGroQAr3mbJlwTJuxFMv250Cjq7WBwUyV2r
# 2XJjsBxheWkxEkWrEfQ9WbBL50yCQul+9fpDuGe6vA0dEbck3/6YfJ+Q3bjCkhKZ
# n743f2O+ZoPVAw0IGNn0iNNjIaQrugLjthGEC4Dwb/Afvmvz+EitCeJyNsl8XfAz
# bA4McJ1oXoic7W6rbcww6JQgAWhnXzPBL96rYonAKBby1bCXWb11wgDXH06JwI+D
# GWRhp+ny5sZwxN3oWjR5YZPYgsQM4r6I+A2ZhSbx2qKUQkGeZQ145u2rbxcRcp+e
# LqzT0IIxpKWXb46KHutOq1YGg69ms0BsNNhlFcnZI3jdIQefw/1oWpxOqTVJ2rNt
# Jz9HWfC5+sHd3+gbbdfg8rhZstA7xgKkdUPdNV8ntPfLEPOTmlimBs8+GRtxPLgV
# OYoChWrc7UpBc9NDYZKqHH5u7/mXQzt1dOFejVaEk147dUlMAyppjOrcPqxYWvqq
# 9/wYGBcW0KjXuazyWDaI6jOwhyEzX3doJCS3sbGfYzsCdqMmdYw=
# =GFiq
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 17 Oct 2024 09:22:44 AM EDT
# gpg:                using RSA key 647F28654894E3BD457199BE38DBBDC86092693E
# gpg: Can't check signature: No public key
This commit is contained in:
Bruce Ashfield 2024-10-21 12:22:48 -04:00
commit 6a3e72e9c6
757 changed files with 11835 additions and 9608 deletions

1
.gitignore vendored
View File

@ -133,7 +133,6 @@ GTAGS
# id-utils files # id-utils files
ID ID
*.orig
*~ *~
\#*# \#*#

View File

@ -3,7 +3,7 @@ KernelVersion:
Contact: linux-iio@vger.kernel.org Contact: linux-iio@vger.kernel.org
Description: Description:
Reading this returns the valid values that can be written to the Reading this returns the valid values that can be written to the
on_altvoltage0_mode attribute: filter_mode attribute:
- auto -> Adjust bandpass filter to track changes in input clock rate. - auto -> Adjust bandpass filter to track changes in input clock rate.
- manual -> disable/unregister the clock rate notifier / input clock tracking. - manual -> disable/unregister the clock rate notifier / input clock tracking.

View File

@ -109,17 +109,17 @@ Get sum of delays, since system boot, for all pids with tgid 5::
CPU count real total virtual total delay total delay average CPU count real total virtual total delay total delay average
8 7000000 6872122 3382277 0.423ms 8 7000000 6872122 3382277 0.423ms
IO count delay total delay average IO count delay total delay average
0 0 0ms 0 0 0.000ms
SWAP count delay total delay average SWAP count delay total delay average
0 0 0ms 0 0 0.000ms
RECLAIM count delay total delay average RECLAIM count delay total delay average
0 0 0ms 0 0 0.000ms
THRASHING count delay total delay average THRASHING count delay total delay average
0 0 0ms 0 0 0.000ms
COMPACT count delay total delay average COMPACT count delay total delay average
0 0 0ms 0 0 0.000ms
WPCOPY count delay total delay average WPCOPY count delay total delay average
0 0 0ms 0 0 0.000ms
Get IO accounting for pid 1, it works only with -p:: Get IO accounting for pid 1, it works only with -p::

View File

@ -4540,6 +4540,16 @@
printk.time= Show timing data prefixed to each printk message line printk.time= Show timing data prefixed to each printk message line
Format: <bool> (1/Y/y=enable, 0/N/n=disable) Format: <bool> (1/Y/y=enable, 0/N/n=disable)
proc_mem.force_override= [KNL]
Format: {always | ptrace | never}
Traditionally /proc/pid/mem allows memory permissions to be
overridden without restrictions. This option may be set to
restrict that. Can be one of:
- 'always': traditional behavior always allows mem overrides.
- 'ptrace': only allow mem overrides for active ptracers.
- 'never': never allow mem overrides.
If not specified, default is the CONFIG_PROC_MEM_* choice.
processor.max_cstate= [HW,ACPI] processor.max_cstate= [HW,ACPI]
Limit processor to maximum C-state Limit processor to maximum C-state
max_cstate=9 overrides any DMI blacklist limit. max_cstate=9 overrides any DMI blacklist limit.

View File

@ -135,6 +135,8 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A710 | #3324338 | ARM64_ERRATUM_3194386 | | ARM | Cortex-A710 | #3324338 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A715 | #3456084 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A720 | #3456091 | ARM64_ERRATUM_3194386 | | ARM | Cortex-A720 | #3456091 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A725 | #3456106 | ARM64_ERRATUM_3194386 | | ARM | Cortex-A725 | #3456106 | ARM64_ERRATUM_3194386 |
@ -171,6 +173,8 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N2 | #3324339 | ARM64_ERRATUM_3194386 | | ARM | Neoverse-N2 | #3324339 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N3 | #3456111 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-V1 | #3324341 | ARM64_ERRATUM_3194386 | | ARM | Neoverse-V1 | #3324341 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-V2 | #3324336 | ARM64_ERRATUM_3194386 | | ARM | Neoverse-V2 | #3324336 | ARM64_ERRATUM_3194386 |

View File

@ -23,7 +23,6 @@ properties:
- ak8963 - ak8963
- ak09911 - ak09911
- ak09912 - ak09912
- ak09916
deprecated: true deprecated: true
reg: reg:

View File

@ -540,7 +540,7 @@ at module load time (for a module) with::
alerts_broken alerts_broken
The addresses are normal I2C addresses. The adapter is the string The addresses are normal I2C addresses. The adapter is the string
name of the adapter, as shown in /sys/class/i2c-adapter/i2c-<n>/name. name of the adapter, as shown in /sys/bus/i2c/devices/i2c-<n>/name.
It is *NOT* i2c-<n> itself. Also, the comparison is done ignoring It is *NOT* i2c-<n> itself. Also, the comparison is done ignoring
spaces, so if the name is "This is an I2C chip" you can say spaces, so if the name is "This is an I2C chip" you can say
adapter_name=ThisisanI2cchip. This is because it's hard to pass in adapter_name=ThisisanI2cchip. This is because it's hard to pass in

View File

@ -17,8 +17,9 @@ a) 等待一个CPU任务为可运行
b) 完成由该任务发起的块I/O同步请求 b) 完成由该任务发起的块I/O同步请求
c) 页面交换 c) 页面交换
d) 内存回收 d) 内存回收
e) 页缓存抖动 e) 抖动
f) 直接规整 f) 直接规整
g) 写保护复制
并将这些统计信息通过taskstats接口提供给用户空间。 并将这些统计信息通过taskstats接口提供给用户空间。
@ -42,7 +43,7 @@ f) 直接规整
include/uapi/linux/taskstats.h include/uapi/linux/taskstats.h
其描述了延时计数相关字段。系统通常以计数器形式返回 CPU、同步块 I/O、交换、内存 其描述了延时计数相关字段。系统通常以计数器形式返回 CPU、同步块 I/O、交换、内存
回收、页缓存抖动、直接规整等的累积延时。 回收、页缓存抖动、直接规整、写保护复制等的累积延时。
取任务某计数器两个连续读数的差值,将得到任务在该时间间隔内等待对应资源的总延时。 取任务某计数器两个连续读数的差值,将得到任务在该时间间隔内等待对应资源的总延时。
@ -91,15 +92,17 @@ getdelays命令的一般格式::
CPU count real total virtual total delay total delay average CPU count real total virtual total delay total delay average
8 7000000 6872122 3382277 0.423ms 8 7000000 6872122 3382277 0.423ms
IO count delay total delay average IO count delay total delay average
0 0 0ms 0 0 0.000ms
SWAP count delay total delay average SWAP count delay total delay average
0 0 0ms 0 0 0.000ms
RECLAIM count delay total delay average RECLAIM count delay total delay average
0 0 0ms 0 0 0.000ms
THRASHING count delay total delay average THRASHING count delay total delay average
0 0 0ms 0 0 0.000ms
COMPACT count delay total delay average COMPACT count delay total delay average
0 0 0ms 0 0 0.000ms
WPCOPY count delay total delay average
0 0 0ms
获取pid为1的IO计数它只和-p一起使用:: 获取pid为1的IO计数它只和-p一起使用::
# ./getdelays -i -p 1 # ./getdelays -i -p 1

View File

@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
VERSION = 6 VERSION = 6
PATCHLEVEL = 1 PATCHLEVEL = 1
SUBLEVEL = 112 SUBLEVEL = 113
EXTRAVERSION = EXTRAVERSION =
NAME = Curry Ramen NAME = Curry Ramen

View File

@ -350,7 +350,7 @@
&iomuxc_lpsr { &iomuxc_lpsr {
pinctrl_enet1_phy_interrupt: enet1phyinterruptgrp { pinctrl_enet1_phy_interrupt: enet1phyinterruptgrp {
fsl,phy = < fsl,pins = <
MX7D_PAD_LPSR_GPIO1_IO02__GPIO1_IO2 0x08 MX7D_PAD_LPSR_GPIO1_IO02__GPIO1_IO2 0x08
>; >;
}; };

View File

@ -690,7 +690,7 @@
compatible = "microchip,sam9x60-rtt", "atmel,at91sam9260-rtt"; compatible = "microchip,sam9x60-rtt", "atmel,at91sam9260-rtt";
reg = <0xfffffe20 0x20>; reg = <0xfffffe20 0x20>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
clocks = <&clk32k 0>; clocks = <&clk32k 1>;
}; };
pit: timer@fffffe40 { pit: timer@fffffe40 {
@ -716,7 +716,7 @@
compatible = "microchip,sam9x60-rtc", "atmel,at91sam9x5-rtc"; compatible = "microchip,sam9x60-rtc", "atmel,at91sam9x5-rtc";
reg = <0xfffffea8 0x100>; reg = <0xfffffea8 0x100>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
clocks = <&clk32k 0>; clocks = <&clk32k 1>;
}; };
watchdog: watchdog@ffffff80 { watchdog: watchdog@ffffff80 {

View File

@ -221,7 +221,7 @@
compatible = "microchip,sama7g5-rtt", "microchip,sam9x60-rtt", "atmel,at91sam9260-rtt"; compatible = "microchip,sama7g5-rtt", "microchip,sam9x60-rtt", "atmel,at91sam9260-rtt";
reg = <0xe001d020 0x30>; reg = <0xe001d020 0x30>;
interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk32k 0>; clocks = <&clk32k 1>;
}; };
clk32k: clock-controller@e001d050 { clk32k: clock-controller@e001d050 {

View File

@ -711,7 +711,7 @@ static int __init aes_init(void)
algname = aes_algs[i].base.cra_name + 2; algname = aes_algs[i].base.cra_name + 2;
drvname = aes_algs[i].base.cra_driver_name + 2; drvname = aes_algs[i].base.cra_driver_name + 2;
basename = aes_algs[i].base.cra_driver_name; basename = aes_algs[i].base.cra_driver_name;
simd = simd_skcipher_create_compat(algname, drvname, basename); simd = simd_skcipher_create_compat(aes_algs + i, algname, drvname, basename);
err = PTR_ERR(simd); err = PTR_ERR(simd);
if (IS_ERR(simd)) if (IS_ERR(simd))
goto unregister_simds; goto unregister_simds;

View File

@ -539,7 +539,7 @@ static int __init aes_init(void)
algname = aes_algs[i].base.cra_name + 2; algname = aes_algs[i].base.cra_name + 2;
drvname = aes_algs[i].base.cra_driver_name + 2; drvname = aes_algs[i].base.cra_driver_name + 2;
basename = aes_algs[i].base.cra_driver_name; basename = aes_algs[i].base.cra_driver_name;
simd = simd_skcipher_create_compat(algname, drvname, basename); simd = simd_skcipher_create_compat(aes_algs + i, algname, drvname, basename);
err = PTR_ERR(simd); err = PTR_ERR(simd);
if (IS_ERR(simd)) if (IS_ERR(simd))
goto unregister_simds; goto unregister_simds;

View File

@ -359,7 +359,7 @@ static unsigned long ep93xx_div_recalc_rate(struct clk_hw *hw,
u32 val = __raw_readl(psc->reg); u32 val = __raw_readl(psc->reg);
u8 index = (val & psc->mask) >> psc->shift; u8 index = (val & psc->mask) >> psc->shift;
if (index > psc->num_div) if (index >= psc->num_div)
return 0; return 0;
return DIV_ROUND_UP_ULL(parent_rate, psc->div[index]); return DIV_ROUND_UP_ULL(parent_rate, psc->div[index]);

View File

@ -66,6 +66,7 @@ static void __init realview_smp_prepare_cpus(unsigned int max_cpus)
return; return;
} }
map = syscon_node_to_regmap(np); map = syscon_node_to_regmap(np);
of_node_put(np);
if (IS_ERR(map)) { if (IS_ERR(map)) {
pr_err("PLATSMP: No syscon regmap\n"); pr_err("PLATSMP: No syscon regmap\n");
return; return;

View File

@ -1012,6 +1012,7 @@ config ARM64_ERRATUM_3194386
* ARM Cortex-A78C erratum 3324346 * ARM Cortex-A78C erratum 3324346
* ARM Cortex-A78C erratum 3324347 * ARM Cortex-A78C erratum 3324347
* ARM Cortex-A710 erratam 3324338 * ARM Cortex-A710 erratam 3324338
* ARM Cortex-A715 errartum 3456084
* ARM Cortex-A720 erratum 3456091 * ARM Cortex-A720 erratum 3456091
* ARM Cortex-A725 erratum 3456106 * ARM Cortex-A725 erratum 3456106
* ARM Cortex-X1 erratum 3324344 * ARM Cortex-X1 erratum 3324344
@ -1022,6 +1023,7 @@ config ARM64_ERRATUM_3194386
* ARM Cortex-X925 erratum 3324334 * ARM Cortex-X925 erratum 3324334
* ARM Neoverse-N1 erratum 3324349 * ARM Neoverse-N1 erratum 3324349
* ARM Neoverse N2 erratum 3324339 * ARM Neoverse N2 erratum 3324339
* ARM Neoverse-N3 erratum 3456111
* ARM Neoverse-V1 erratum 3324341 * ARM Neoverse-V1 erratum 3324341
* ARM Neoverse V2 erratum 3324336 * ARM Neoverse V2 erratum 3324336
* ARM Neoverse-V3 erratum 3312417 * ARM Neoverse-V3 erratum 3312417

View File

@ -31,7 +31,7 @@
device_type = "memory"; device_type = "memory";
reg = <0x0 0x80000000 0x3da00000>, reg = <0x0 0x80000000 0x3da00000>,
<0x0 0xc0000000 0x40000000>, <0x0 0xc0000000 0x40000000>,
<0x8 0x80000000 0x40000000>; <0x8 0x80000000 0x80000000>;
}; };
gpio-keys { gpio-keys {

View File

@ -922,6 +922,7 @@
usb2-lpm-disable; usb2-lpm-disable;
vusb33-supply = <&mt6359_vusb_ldo_reg>; vusb33-supply = <&mt6359_vusb_ldo_reg>;
vbus-supply = <&usb_vbus>; vbus-supply = <&usb_vbus>;
mediatek,u3p-dis-msk = <1>;
}; };
#include <arm/cros-ec-keyboard.dtsi> #include <arm/cros-ec-keyboard.dtsi>

View File

@ -2125,7 +2125,7 @@
"jedec,ufs-2.0"; "jedec,ufs-2.0";
reg = <0 0x01d84000 0 0x3000>; reg = <0 0x01d84000 0 0x3000>;
interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
phys = <&ufs_mem_phy>; phys = <&ufs_mem_phy_lanes>;
phy-names = "ufsphy"; phy-names = "ufsphy";
lanes-per-direction = <2>; lanes-per-direction = <2>;
#reset-cells = <1>; #reset-cells = <1>;
@ -2169,8 +2169,10 @@
ufs_mem_phy: phy@1d87000 { ufs_mem_phy: phy@1d87000 {
compatible = "qcom,sm8250-qmp-ufs-phy"; compatible = "qcom,sm8250-qmp-ufs-phy";
reg = <0 0x01d87000 0 0x1000>; reg = <0 0x01d87000 0 0x1c0>;
#address-cells = <2>;
#size-cells = <2>;
ranges;
clock-names = "ref", clock-names = "ref",
"ref_aux"; "ref_aux";
clocks = <&rpmhcc RPMH_CXO_CLK>, clocks = <&rpmhcc RPMH_CXO_CLK>,
@ -2178,12 +2180,18 @@
resets = <&ufs_mem_hc 0>; resets = <&ufs_mem_hc 0>;
reset-names = "ufsphy"; reset-names = "ufsphy";
status = "disabled";
power-domains = <&gcc UFS_PHY_GDSC>; power-domains = <&gcc UFS_PHY_GDSC>;
#phy-cells = <0>; ufs_mem_phy_lanes: phy@1d87400 {
reg = <0 0x01d87400 0 0x16c>,
status = "disabled"; <0 0x01d87600 0 0x200>,
<0 0x01d87c00 0 0x200>,
<0 0x01d87800 0 0x16c>,
<0 0x01d87a00 0 0x200>;
#phy-cells = <0>;
};
}; };
ipa_virt: interconnect@1e00000 { ipa_virt: interconnect@1e00000 {

View File

@ -135,8 +135,8 @@
#interrupt-cells = <3>; #interrupt-cells = <3>;
#address-cells = <0>; #address-cells = <0>;
interrupt-controller; interrupt-controller;
reg = <0x0 0x11900000 0 0x40000>, reg = <0x0 0x11900000 0 0x20000>,
<0x0 0x11940000 0 0x60000>; <0x0 0x11940000 0 0x40000>;
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>; interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
}; };
}; };

View File

@ -788,8 +788,8 @@
#interrupt-cells = <3>; #interrupt-cells = <3>;
#address-cells = <0>; #address-cells = <0>;
interrupt-controller; interrupt-controller;
reg = <0x0 0x11900000 0 0x40000>, reg = <0x0 0x11900000 0 0x20000>,
<0x0 0x11940000 0 0x60000>; <0x0 0x11940000 0 0x40000>;
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>; interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
}; };

View File

@ -794,8 +794,8 @@
#interrupt-cells = <3>; #interrupt-cells = <3>;
#address-cells = <0>; #address-cells = <0>;
interrupt-controller; interrupt-controller;
reg = <0x0 0x11900000 0 0x40000>, reg = <0x0 0x11900000 0 0x20000>,
<0x0 0x11940000 0 0x60000>; <0x0 0x11940000 0 0x40000>;
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>; interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
}; };

View File

@ -32,12 +32,12 @@
backlight: edp-backlight { backlight: edp-backlight {
compatible = "pwm-backlight"; compatible = "pwm-backlight";
power-supply = <&vcc_12v>; power-supply = <&vcc_12v>;
pwms = <&pwm0 0 740740 0>; pwms = <&pwm0 0 125000 0>;
}; };
bat: battery { bat: battery {
compatible = "simple-battery"; compatible = "simple-battery";
charge-full-design-microamp-hours = <9800000>; charge-full-design-microamp-hours = <10000000>;
voltage-max-design-microvolt = <4350000>; voltage-max-design-microvolt = <4350000>;
voltage-min-design-microvolt = <3000000>; voltage-min-design-microvolt = <3000000>;
}; };

View File

@ -111,7 +111,7 @@
no-map; no-map;
}; };
c66_1_dma_memory_region: c66-dma-memory@a6000000 { c66_0_dma_memory_region: c66-dma-memory@a6000000 {
compatible = "shared-dma-pool"; compatible = "shared-dma-pool";
reg = <0x00 0xa6000000 0x00 0x100000>; reg = <0x00 0xa6000000 0x00 0x100000>;
no-map; no-map;
@ -123,7 +123,7 @@
no-map; no-map;
}; };
c66_0_dma_memory_region: c66-dma-memory@a7000000 { c66_1_dma_memory_region: c66-dma-memory@a7000000 {
compatible = "shared-dma-pool"; compatible = "shared-dma-pool";
reg = <0x00 0xa7000000 0x00 0x100000>; reg = <0x00 0xa7000000 0x00 0x100000>;
no-map; no-map;

View File

@ -82,6 +82,7 @@
#define ARM_CPU_PART_CORTEX_A510 0xD46 #define ARM_CPU_PART_CORTEX_A510 0xD46
#define ARM_CPU_PART_CORTEX_A520 0xD80 #define ARM_CPU_PART_CORTEX_A520 0xD80
#define ARM_CPU_PART_CORTEX_A710 0xD47 #define ARM_CPU_PART_CORTEX_A710 0xD47
#define ARM_CPU_PART_CORTEX_A715 0xD4D
#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
@ -93,6 +94,7 @@
#define ARM_CPU_PART_NEOVERSE_V3 0xD84 #define ARM_CPU_PART_NEOVERSE_V3 0xD84
#define ARM_CPU_PART_CORTEX_X925 0xD85 #define ARM_CPU_PART_CORTEX_X925 0xD85
#define ARM_CPU_PART_CORTEX_A725 0xD87 #define ARM_CPU_PART_CORTEX_A725 0xD87
#define ARM_CPU_PART_NEOVERSE_N3 0xD8E
#define APM_CPU_PART_XGENE 0x000 #define APM_CPU_PART_XGENE 0x000
#define APM_CPU_VAR_POTENZA 0x00 #define APM_CPU_VAR_POTENZA 0x00
@ -156,6 +158,7 @@
#define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510) #define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510)
#define MIDR_CORTEX_A520 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A520) #define MIDR_CORTEX_A520 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A520)
#define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710) #define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
#define MIDR_CORTEX_A715 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A715)
#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)
@ -167,6 +170,7 @@
#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3) #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_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_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725)
#define MIDR_NEOVERSE_N3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N3)
#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

@ -442,6 +442,7 @@ static const struct midr_range erratum_spec_ssbs_list[] = {
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78), MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C), MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A710), MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A715),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A720), MIDR_ALL_VERSIONS(MIDR_CORTEX_A720),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A725), MIDR_ALL_VERSIONS(MIDR_CORTEX_A725),
MIDR_ALL_VERSIONS(MIDR_CORTEX_X1), MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
@ -452,6 +453,7 @@ static const struct midr_range erratum_spec_ssbs_list[] = {
MIDR_ALL_VERSIONS(MIDR_CORTEX_X925), MIDR_ALL_VERSIONS(MIDR_CORTEX_X925),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N3),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3),

View File

@ -82,7 +82,6 @@ CONFIG_ZSWAP=y
CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD=y CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD=y
CONFIG_ZPOOL=y CONFIG_ZPOOL=y
CONFIG_ZBUD=y CONFIG_ZBUD=y
CONFIG_Z3FOLD=y
CONFIG_ZSMALLOC=m CONFIG_ZSMALLOC=m
CONFIG_NET=y CONFIG_NET=y
CONFIG_PACKET=y CONFIG_PACKET=y

View File

@ -222,6 +222,7 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
if (bus) { if (bus) {
memcpy(bus->sysdata, info->cfg, sizeof(struct pci_config_window)); memcpy(bus->sysdata, info->cfg, sizeof(struct pci_config_window));
kfree(info); kfree(info);
kfree(root_ops);
} else { } else {
struct pci_bus *child; struct pci_bus *child;

View File

@ -115,7 +115,7 @@ asmlinkage int m68k_clone(struct pt_regs *regs)
{ {
/* regs will be equal to current_pt_regs() */ /* regs will be equal to current_pt_regs() */
struct kernel_clone_args args = { struct kernel_clone_args args = {
.flags = regs->d1 & ~CSIGNAL, .flags = (u32)(regs->d1) & ~CSIGNAL,
.pidfd = (int __user *)regs->d3, .pidfd = (int __user *)regs->d3,
.child_tid = (int __user *)regs->d4, .child_tid = (int __user *)regs->d4,
.parent_tid = (int __user *)regs->d3, .parent_tid = (int __user *)regs->d3,

View File

@ -1038,8 +1038,7 @@ ENTRY_CFI(intr_save) /* for os_hpmc */
STREG %r16, PT_ISR(%r29) STREG %r16, PT_ISR(%r29)
STREG %r17, PT_IOR(%r29) STREG %r17, PT_IOR(%r29)
#if 0 && defined(CONFIG_64BIT) #if defined(CONFIG_64BIT)
/* Revisit when we have 64-bit code above 4Gb */
b,n intr_save2 b,n intr_save2
skip_save_ior: skip_save_ior:
@ -1047,8 +1046,7 @@ skip_save_ior:
* need to adjust iasq/iaoq here in the same way we adjusted isr/ior * need to adjust iasq/iaoq here in the same way we adjusted isr/ior
* above. * above.
*/ */
extrd,u,* %r8,PSW_W_BIT,1,%r1 bb,COND(>=),n %r8,PSW_W_BIT,intr_save2
cmpib,COND(=),n 1,%r1,intr_save2
LDREG PT_IASQ0(%r29), %r16 LDREG PT_IASQ0(%r29), %r16
LDREG PT_IAOQ0(%r29), %r17 LDREG PT_IAOQ0(%r29), %r17
/* adjust iasq/iaoq */ /* adjust iasq/iaoq */

View File

@ -232,10 +232,10 @@ linux_gateway_entry:
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
ldil L%sys_call_table, %r1 ldil L%sys_call_table, %r1
or,= %r2,%r2,%r2 or,ev %r2,%r2,%r2
addil L%(sys_call_table64-sys_call_table), %r1 ldil L%sys_call_table64, %r1
ldo R%sys_call_table(%r1), %r19 ldo R%sys_call_table(%r1), %r19
or,= %r2,%r2,%r2 or,ev %r2,%r2,%r2
ldo R%sys_call_table64(%r1), %r19 ldo R%sys_call_table64(%r1), %r19
#else #else
load32 sys_call_table, %r19 load32 sys_call_table, %r19
@ -368,10 +368,10 @@ tracesys_next:
extrd,u %r19,63,1,%r2 /* W hidden in bottom bit */ extrd,u %r19,63,1,%r2 /* W hidden in bottom bit */
ldil L%sys_call_table, %r1 ldil L%sys_call_table, %r1
or,= %r2,%r2,%r2 or,ev %r2,%r2,%r2
addil L%(sys_call_table64-sys_call_table), %r1 ldil L%sys_call_table64, %r1
ldo R%sys_call_table(%r1), %r19 ldo R%sys_call_table(%r1), %r19
or,= %r2,%r2,%r2 or,ev %r2,%r2,%r2
ldo R%sys_call_table64(%r1), %r19 ldo R%sys_call_table64(%r1), %r19
#else #else
load32 sys_call_table, %r19 load32 sys_call_table, %r19
@ -1310,6 +1310,8 @@ ENTRY(sys_call_table)
END(sys_call_table) END(sys_call_table)
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
#undef __SYSCALL_WITH_COMPAT
#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native)
.align 8 .align 8
ENTRY(sys_call_table64) ENTRY(sys_call_table64)
#include <asm/syscall_table_64.h> /* 64-bit syscalls */ #include <asm/syscall_table_64.h> /* 64-bit syscalls */

View File

@ -1,6 +1,12 @@
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
source "arch/powerpc/platforms/Kconfig.cputype" source "arch/powerpc/platforms/Kconfig.cputype"
config CC_HAS_ELFV2
def_bool PPC64 && $(cc-option, -mabi=elfv2)
config CC_HAS_PREFIXED
def_bool PPC64 && $(cc-option, -mcpu=power10 -mprefixed)
config 32BIT config 32BIT
bool bool
default y if PPC32 default y if PPC32
@ -583,6 +589,23 @@ config KEXEC_FILE
config ARCH_HAS_KEXEC_PURGATORY config ARCH_HAS_KEXEC_PURGATORY
def_bool KEXEC_FILE def_bool KEXEC_FILE
config PPC64_BIG_ENDIAN_ELF_ABI_V2
bool "Build big-endian kernel using ELF ABI V2 (EXPERIMENTAL)"
depends on PPC64 && CPU_BIG_ENDIAN
depends on CC_HAS_ELFV2
depends on LD_VERSION >= 22400 || LLD_VERSION >= 150000
help
This builds the kernel image using the "Power Architecture 64-Bit ELF
V2 ABI Specification", which has a reduced stack overhead and faster
function calls. This internal kernel ABI option does not affect
userspace compatibility.
The V2 ABI is standard for 64-bit little-endian, but for big-endian
it is less well tested by kernel and toolchain. However some distros
build userspace this way, and it can produce a functioning kernel.
This requires GCC and binutils 2.24 or newer.
config RELOCATABLE config RELOCATABLE
bool "Build a relocatable kernel" bool "Build a relocatable kernel"
depends on PPC64 || (FLATMEM && (44x || PPC_85xx)) depends on PPC64 || (FLATMEM && (44x || PPC_85xx))

View File

@ -176,7 +176,11 @@ ifdef CONFIG_476FPE_ERR46
endif endif
# No prefix or pcrel # No prefix or pcrel
ifdef CONFIG_PPC_KERNEL_PREFIXED
KBUILD_CFLAGS += $(call cc-option,-mprefixed)
else
KBUILD_CFLAGS += $(call cc-option,-mno-prefixed) KBUILD_CFLAGS += $(call cc-option,-mno-prefixed)
endif
KBUILD_CFLAGS += $(call cc-option,-mno-pcrel) KBUILD_CFLAGS += $(call cc-option,-mno-pcrel)
# No AltiVec or VSX or MMA instructions when building kernel # No AltiVec or VSX or MMA instructions when building kernel

View File

@ -39,6 +39,12 @@
#define STDX_BE stringify_in_c(stdbrx) #define STDX_BE stringify_in_c(stdbrx)
#endif #endif
#ifdef CONFIG_CC_IS_CLANG
#define DS_FORM_CONSTRAINT "Z<>"
#else
#define DS_FORM_CONSTRAINT "YZ<>"
#endif
#else /* 32-bit */ #else /* 32-bit */
/* operations for longs and pointers */ /* operations for longs and pointers */

View File

@ -11,6 +11,7 @@
#include <asm/cmpxchg.h> #include <asm/cmpxchg.h>
#include <asm/barrier.h> #include <asm/barrier.h>
#include <asm/asm-const.h> #include <asm/asm-const.h>
#include <asm/asm-compat.h>
/* /*
* Since *_return_relaxed and {cmp}xchg_relaxed are implemented with * Since *_return_relaxed and {cmp}xchg_relaxed are implemented with
@ -27,14 +28,22 @@ static __inline__ int arch_atomic_read(const atomic_t *v)
{ {
int t; int t;
__asm__ __volatile__("lwz%U1%X1 %0,%1" : "=r"(t) : "m<>"(v->counter)); /* -mprefixed can generate offsets beyond range, fall back hack */
if (IS_ENABLED(CONFIG_PPC_KERNEL_PREFIXED))
__asm__ __volatile__("lwz %0,0(%1)" : "=r"(t) : "b"(&v->counter));
else
__asm__ __volatile__("lwz%U1%X1 %0,%1" : "=r"(t) : "m<>"(v->counter));
return t; return t;
} }
static __inline__ void arch_atomic_set(atomic_t *v, int i) static __inline__ void arch_atomic_set(atomic_t *v, int i)
{ {
__asm__ __volatile__("stw%U0%X0 %1,%0" : "=m<>"(v->counter) : "r"(i)); /* -mprefixed can generate offsets beyond range, fall back hack */
if (IS_ENABLED(CONFIG_PPC_KERNEL_PREFIXED))
__asm__ __volatile__("stw %1,0(%2)" : "=m"(v->counter) : "r"(i), "b"(&v->counter));
else
__asm__ __volatile__("stw%U0%X0 %1,%0" : "=m<>"(v->counter) : "r"(i));
} }
#define ATOMIC_OP(op, asm_op, suffix, sign, ...) \ #define ATOMIC_OP(op, asm_op, suffix, sign, ...) \
@ -226,14 +235,22 @@ static __inline__ s64 arch_atomic64_read(const atomic64_t *v)
{ {
s64 t; s64 t;
__asm__ __volatile__("ld%U1%X1 %0,%1" : "=r"(t) : "m<>"(v->counter)); /* -mprefixed can generate offsets beyond range, fall back hack */
if (IS_ENABLED(CONFIG_PPC_KERNEL_PREFIXED))
__asm__ __volatile__("ld %0,0(%1)" : "=r"(t) : "b"(&v->counter));
else
__asm__ __volatile__("ld%U1%X1 %0,%1" : "=r"(t) : DS_FORM_CONSTRAINT (v->counter));
return t; return t;
} }
static __inline__ void arch_atomic64_set(atomic64_t *v, s64 i) static __inline__ void arch_atomic64_set(atomic64_t *v, s64 i)
{ {
__asm__ __volatile__("std%U0%X0 %1,%0" : "=m<>"(v->counter) : "r"(i)); /* -mprefixed can generate offsets beyond range, fall back hack */
if (IS_ENABLED(CONFIG_PPC_KERNEL_PREFIXED))
__asm__ __volatile__("std %1,0(%2)" : "=m"(v->counter) : "r"(i), "b"(&v->counter));
else
__asm__ __volatile__("std%U0%X0 %1,%0" : "=" DS_FORM_CONSTRAINT (v->counter) : "r"(i));
} }
#define ATOMIC64_OP(op, asm_op) \ #define ATOMIC64_OP(op, asm_op) \

View File

@ -97,6 +97,42 @@ extern bool isa_io_special;
* *
*/ */
/* -mprefixed can generate offsets beyond range, fall back hack */
#ifdef CONFIG_PPC_KERNEL_PREFIXED
#define DEF_MMIO_IN_X(name, size, insn) \
static inline u##size name(const volatile u##size __iomem *addr) \
{ \
u##size ret; \
__asm__ __volatile__("sync;"#insn" %0,0,%1;twi 0,%0,0;isync" \
: "=r" (ret) : "r" (addr) : "memory"); \
return ret; \
}
#define DEF_MMIO_OUT_X(name, size, insn) \
static inline void name(volatile u##size __iomem *addr, u##size val) \
{ \
__asm__ __volatile__("sync;"#insn" %1,0,%0" \
: : "r" (addr), "r" (val) : "memory"); \
mmiowb_set_pending(); \
}
#define DEF_MMIO_IN_D(name, size, insn) \
static inline u##size name(const volatile u##size __iomem *addr) \
{ \
u##size ret; \
__asm__ __volatile__("sync;"#insn" %0,0(%1);twi 0,%0,0;isync"\
: "=r" (ret) : "b" (addr) : "memory"); \
return ret; \
}
#define DEF_MMIO_OUT_D(name, size, insn) \
static inline void name(volatile u##size __iomem *addr, u##size val) \
{ \
__asm__ __volatile__("sync;"#insn" %1,0(%0)" \
: : "b" (addr), "r" (val) : "memory"); \
mmiowb_set_pending(); \
}
#else
#define DEF_MMIO_IN_X(name, size, insn) \ #define DEF_MMIO_IN_X(name, size, insn) \
static inline u##size name(const volatile u##size __iomem *addr) \ static inline u##size name(const volatile u##size __iomem *addr) \
{ \ { \
@ -130,6 +166,7 @@ static inline void name(volatile u##size __iomem *addr, u##size val) \
: "=m<>" (*addr) : "r" (val) : "memory"); \ : "=m<>" (*addr) : "r" (val) : "memory"); \
mmiowb_set_pending(); \ mmiowb_set_pending(); \
} }
#endif
DEF_MMIO_IN_D(in_8, 8, lbz); DEF_MMIO_IN_D(in_8, 8, lbz);
DEF_MMIO_OUT_D(out_8, 8, stb); DEF_MMIO_OUT_D(out_8, 8, stb);

View File

@ -6,6 +6,7 @@
#include <asm/page.h> #include <asm/page.h>
#include <asm/extable.h> #include <asm/extable.h>
#include <asm/kup.h> #include <asm/kup.h>
#include <asm/asm-compat.h>
#ifdef __powerpc64__ #ifdef __powerpc64__
/* We use TASK_SIZE_USER64 as TASK_SIZE is not constant */ /* We use TASK_SIZE_USER64 as TASK_SIZE is not constant */
@ -71,19 +72,25 @@ __pu_failed: \
* because we do not write to any memory gcc knows about, so there * because we do not write to any memory gcc knows about, so there
* are no aliasing issues. * are no aliasing issues.
*/ */
/* -mprefixed can generate offsets beyond range, fall back hack */
#ifdef CONFIG_PPC_KERNEL_PREFIXED
#define __put_user_asm_goto(x, addr, label, op) \
asm_volatile_goto( \
"1: " op " %0,0(%1) # put_user\n" \
EX_TABLE(1b, %l2) \
: \
: "r" (x), "b" (addr) \
: \
: label)
#else
#define __put_user_asm_goto(x, addr, label, op) \ #define __put_user_asm_goto(x, addr, label, op) \
asm goto( \ asm goto( \
"1: " op "%U1%X1 %0,%1 # put_user\n" \ "1: " op "%U1%X1 %0,%1 # put_user\n" \
EX_TABLE(1b, %l2) \ EX_TABLE(1b, %l2) \
: \ : \
: "r" (x), "m<>" (*addr) \ : "r" (x), "m<>" (*addr) \
: \ : \
: label) : label)
#ifdef CONFIG_CC_IS_CLANG
#define DS_FORM_CONSTRAINT "Z<>"
#else
#define DS_FORM_CONSTRAINT "YZ<>"
#endif #endif
#ifdef __powerpc64__ #ifdef __powerpc64__
@ -142,14 +149,26 @@ do { \
#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT #ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
/* -mprefixed can generate offsets beyond range, fall back hack */
#ifdef CONFIG_PPC_KERNEL_PREFIXED
#define __get_user_asm_goto(x, addr, label, op) \
asm_volatile_goto( \
"1: "op" %0,0(%1) # get_user\n" \
EX_TABLE(1b, %l2) \
: "=r" (x) \
: "b" (addr) \
: \
: label)
#else
#define __get_user_asm_goto(x, addr, label, op) \ #define __get_user_asm_goto(x, addr, label, op) \
asm_goto_output( \ asm_goto_output( \
"1: "op"%U1%X1 %0, %1 # get_user\n" \ "1: "op"%U1%X1 %0, %1 # get_user\n" \
EX_TABLE(1b, %l2) \ EX_TABLE(1b, %l2) \
: "=r" (x) \ : "=r" (x) \
: "m<>" (*addr) \ : "m<>" (*addr) \
: \ : \
: label) : label)
#endif
#ifdef __powerpc64__ #ifdef __powerpc64__
#define __get_user_asm2_goto(x, addr, label) \ #define __get_user_asm2_goto(x, addr, label) \

View File

@ -111,6 +111,21 @@ extern struct vdso_arch_data *vdso_data;
addi \ptr, \ptr, (_vdso_datapage - 999b)@l addi \ptr, \ptr, (_vdso_datapage - 999b)@l
.endm .endm
#include <asm/asm-offsets.h>
#include <asm/page.h>
.macro get_realdatapage ptr scratch
get_datapage \ptr
#ifdef CONFIG_TIME_NS
lwz \scratch, VDSO_CLOCKMODE_OFFSET(\ptr)
xoris \scratch, \scratch, VDSO_CLOCKMODE_TIMENS@h
xori \scratch, \scratch, VDSO_CLOCKMODE_TIMENS@l
cntlzw \scratch, \scratch
rlwinm \scratch, \scratch, PAGE_SHIFT - 5, 1 << PAGE_SHIFT
add \ptr, \ptr, \scratch
#endif
.endm
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */

View File

@ -347,6 +347,8 @@ int main(void)
#else #else
OFFSET(CFG_SYSCALL_MAP32, vdso_arch_data, syscall_map); OFFSET(CFG_SYSCALL_MAP32, vdso_arch_data, syscall_map);
#endif #endif
OFFSET(VDSO_CLOCKMODE_OFFSET, vdso_arch_data, data[0].clock_mode);
DEFINE(VDSO_CLOCKMODE_TIMENS, VDSO_CLOCKMODE_TIMENS);
#ifdef CONFIG_BUG #ifdef CONFIG_BUG
DEFINE(BUG_ENTRY_SIZE, sizeof(struct bug_entry)); DEFINE(BUG_ENTRY_SIZE, sizeof(struct bug_entry));

View File

@ -40,12 +40,12 @@
#include "head_32.h" #include "head_32.h"
.macro compare_to_kernel_boundary scratch, addr .macro compare_to_kernel_boundary scratch, addr
#if CONFIG_TASK_SIZE <= 0x80000000 && CONFIG_PAGE_OFFSET >= 0x80000000 #if CONFIG_TASK_SIZE <= 0x80000000 && MODULES_VADDR >= 0x80000000
/* By simply checking Address >= 0x80000000, we know if its a kernel address */ /* By simply checking Address >= 0x80000000, we know if its a kernel address */
not. \scratch, \addr not. \scratch, \addr
#else #else
rlwinm \scratch, \addr, 16, 0xfff8 rlwinm \scratch, \addr, 16, 0xfff8
cmpli cr0, \scratch, PAGE_OFFSET@h cmpli cr0, \scratch, TASK_SIZE@h
#endif #endif
.endm .endm
@ -403,7 +403,7 @@ FixupDAR:/* Entry point for dcbx workaround. */
mfspr r10, SPRN_SRR0 mfspr r10, SPRN_SRR0
mtspr SPRN_MD_EPN, r10 mtspr SPRN_MD_EPN, r10
rlwinm r11, r10, 16, 0xfff8 rlwinm r11, r10, 16, 0xfff8
cmpli cr1, r11, PAGE_OFFSET@h cmpli cr1, r11, TASK_SIZE@h
mfspr r11, SPRN_M_TWB /* Get level 1 table */ mfspr r11, SPRN_M_TWB /* Get level 1 table */
blt+ cr1, 3f blt+ cr1, 3f

View File

@ -194,6 +194,8 @@ __ftrace_make_nop(struct module *mod,
* get corrupted. * get corrupted.
* *
* Use a b +8 to jump over the load. * Use a b +8 to jump over the load.
* XXX: could make PCREL depend on MPROFILE_KERNEL
* XXX: check PCREL && MPROFILE_KERNEL calling sequence
*/ */
if (IS_ENABLED(CONFIG_MPROFILE_KERNEL) || IS_ENABLED(CONFIG_PPC32)) if (IS_ENABLED(CONFIG_MPROFILE_KERNEL) || IS_ENABLED(CONFIG_PPC32))
pop = ppc_inst(PPC_RAW_NOP()); pop = ppc_inst(PPC_RAW_NOP());

View File

@ -30,7 +30,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
mflr r12 mflr r12
.cfi_register lr,r12 .cfi_register lr,r12
get_datapage r10 get_realdatapage r10, r11
mtlr r12 mtlr r12
.cfi_restore lr .cfi_restore lr
#endif #endif

View File

@ -28,7 +28,7 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_map)
mflr r12 mflr r12
.cfi_register lr,r12 .cfi_register lr,r12
mr. r4,r3 mr. r4,r3
get_datapage r3 get_realdatapage r3, r11
mtlr r12 mtlr r12
#ifdef __powerpc64__ #ifdef __powerpc64__
addi r3,r3,CFG_SYSCALL_MAP64 addi r3,r3,CFG_SYSCALL_MAP64
@ -52,7 +52,7 @@ V_FUNCTION_BEGIN(__kernel_get_tbfreq)
.cfi_startproc .cfi_startproc
mflr r12 mflr r12
.cfi_register lr,r12 .cfi_register lr,r12
get_datapage r3 get_realdatapage r3, r11
#ifndef __powerpc64__ #ifndef __powerpc64__
lwz r4,(CFG_TB_TICKS_PER_SEC + 4)(r3) lwz r4,(CFG_TB_TICKS_PER_SEC + 4)(r3)
#endif #endif

View File

@ -147,11 +147,11 @@ unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)
mmu_mapin_immr(); mmu_mapin_immr();
mmu_mapin_ram_chunk(0, boundary, PAGE_KERNEL_TEXT, true); mmu_mapin_ram_chunk(0, boundary, PAGE_KERNEL_X, true);
if (debug_pagealloc_enabled_or_kfence()) { if (debug_pagealloc_enabled_or_kfence()) {
top = boundary; top = boundary;
} else { } else {
mmu_mapin_ram_chunk(boundary, einittext8, PAGE_KERNEL_TEXT, true); mmu_mapin_ram_chunk(boundary, einittext8, PAGE_KERNEL_X, true);
mmu_mapin_ram_chunk(einittext8, top, PAGE_KERNEL, true); mmu_mapin_ram_chunk(einittext8, top, PAGE_KERNEL, true);
} }

View File

@ -176,6 +176,7 @@ config POWER10_CPU
bool "POWER10" bool "POWER10"
depends on PPC_BOOK3S_64 depends on PPC_BOOK3S_64
select ARCH_HAS_FAST_MULTIPLIER select ARCH_HAS_FAST_MULTIPLIER
select PPC_HAVE_PREFIXED_SUPPORT
config E5500_CPU config E5500_CPU
bool "Freescale e5500" bool "Freescale e5500"
@ -449,6 +450,22 @@ config PPC_RADIX_MMU_DEFAULT
If you're unsure, say Y. If you're unsure, say Y.
config PPC_KERNEL_PREFIXED
depends on PPC_HAVE_PREFIXED_SUPPORT
depends on CC_HAS_PREFIXED
default n
bool "Build Kernel with Prefixed Instructions"
help
POWER10 and later CPUs support prefixed instructions, 8 byte
instructions that include large immediate, pc relative addressing,
and various floating point, vector, MMA.
This option builds the kernel with prefixed instructions, and
allows a pc relative addressing option to be selected.
Kernel support for prefixed instructions in applications and guests
is not affected by this option.
config PPC_KUEP config PPC_KUEP
bool "Kernel Userspace Execution Prevention" if !40x bool "Kernel Userspace Execution Prevention" if !40x
default y if !40x default y if !40x
@ -485,6 +502,9 @@ config PPC_MMU_NOHASH
config PPC_HAVE_PMU_SUPPORT config PPC_HAVE_PMU_SUPPORT
bool bool
config PPC_HAVE_PREFIXED_SUPPORT
bool
config PMU_SYSFS config PMU_SYSFS
bool "Create PMU SPRs sysfs file" bool "Create PMU SPRs sysfs file"
default n default n
@ -585,10 +605,10 @@ config CPU_LITTLE_ENDIAN
endchoice endchoice
config PPC64_ELF_ABI_V1 config PPC64_ELF_ABI_V1
def_bool PPC64 && CPU_BIG_ENDIAN def_bool PPC64 && (CPU_BIG_ENDIAN && !PPC64_BIG_ENDIAN_ELF_ABI_V2)
config PPC64_ELF_ABI_V2 config PPC64_ELF_ABI_V2
def_bool PPC64 && CPU_LITTLE_ENDIAN def_bool PPC64 && !PPC64_ELF_ABI_V1
config PPC64_BOOT_WRAPPER config PPC64_BOOT_WRAPPER
def_bool n def_bool n

View File

@ -343,23 +343,6 @@ int handle_dlpar_errorlog(struct pseries_hp_errorlog *hp_elog)
{ {
int rc; int rc;
/* pseries error logs are in BE format, convert to cpu type */
switch (hp_elog->id_type) {
case PSERIES_HP_ELOG_ID_DRC_COUNT:
hp_elog->_drc_u.drc_count =
be32_to_cpu(hp_elog->_drc_u.drc_count);
break;
case PSERIES_HP_ELOG_ID_DRC_INDEX:
hp_elog->_drc_u.drc_index =
be32_to_cpu(hp_elog->_drc_u.drc_index);
break;
case PSERIES_HP_ELOG_ID_DRC_IC:
hp_elog->_drc_u.ic.count =
be32_to_cpu(hp_elog->_drc_u.ic.count);
hp_elog->_drc_u.ic.index =
be32_to_cpu(hp_elog->_drc_u.ic.index);
}
switch (hp_elog->resource) { switch (hp_elog->resource) {
case PSERIES_HP_ELOG_RESOURCE_MEM: case PSERIES_HP_ELOG_RESOURCE_MEM:
rc = dlpar_memory(hp_elog); rc = dlpar_memory(hp_elog);

View File

@ -748,7 +748,7 @@ int dlpar_cpu(struct pseries_hp_errorlog *hp_elog)
u32 drc_index; u32 drc_index;
int rc; int rc;
drc_index = hp_elog->_drc_u.drc_index; drc_index = be32_to_cpu(hp_elog->_drc_u.drc_index);
lock_device_hotplug(); lock_device_hotplug();

View File

@ -876,16 +876,16 @@ int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
case PSERIES_HP_ELOG_ACTION_ADD: case PSERIES_HP_ELOG_ACTION_ADD:
switch (hp_elog->id_type) { switch (hp_elog->id_type) {
case PSERIES_HP_ELOG_ID_DRC_COUNT: case PSERIES_HP_ELOG_ID_DRC_COUNT:
count = hp_elog->_drc_u.drc_count; count = be32_to_cpu(hp_elog->_drc_u.drc_count);
rc = dlpar_memory_add_by_count(count); rc = dlpar_memory_add_by_count(count);
break; break;
case PSERIES_HP_ELOG_ID_DRC_INDEX: case PSERIES_HP_ELOG_ID_DRC_INDEX:
drc_index = hp_elog->_drc_u.drc_index; drc_index = be32_to_cpu(hp_elog->_drc_u.drc_index);
rc = dlpar_memory_add_by_index(drc_index); rc = dlpar_memory_add_by_index(drc_index);
break; break;
case PSERIES_HP_ELOG_ID_DRC_IC: case PSERIES_HP_ELOG_ID_DRC_IC:
count = hp_elog->_drc_u.ic.count; count = be32_to_cpu(hp_elog->_drc_u.ic.count);
drc_index = hp_elog->_drc_u.ic.index; drc_index = be32_to_cpu(hp_elog->_drc_u.ic.index);
rc = dlpar_memory_add_by_ic(count, drc_index); rc = dlpar_memory_add_by_ic(count, drc_index);
break; break;
default: default:
@ -897,16 +897,16 @@ int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
case PSERIES_HP_ELOG_ACTION_REMOVE: case PSERIES_HP_ELOG_ACTION_REMOVE:
switch (hp_elog->id_type) { switch (hp_elog->id_type) {
case PSERIES_HP_ELOG_ID_DRC_COUNT: case PSERIES_HP_ELOG_ID_DRC_COUNT:
count = hp_elog->_drc_u.drc_count; count = be32_to_cpu(hp_elog->_drc_u.drc_count);
rc = dlpar_memory_remove_by_count(count); rc = dlpar_memory_remove_by_count(count);
break; break;
case PSERIES_HP_ELOG_ID_DRC_INDEX: case PSERIES_HP_ELOG_ID_DRC_INDEX:
drc_index = hp_elog->_drc_u.drc_index; drc_index = be32_to_cpu(hp_elog->_drc_u.drc_index);
rc = dlpar_memory_remove_by_index(drc_index); rc = dlpar_memory_remove_by_index(drc_index);
break; break;
case PSERIES_HP_ELOG_ID_DRC_IC: case PSERIES_HP_ELOG_ID_DRC_IC:
count = hp_elog->_drc_u.ic.count; count = be32_to_cpu(hp_elog->_drc_u.ic.count);
drc_index = hp_elog->_drc_u.ic.index; drc_index = be32_to_cpu(hp_elog->_drc_u.ic.index);
rc = dlpar_memory_remove_by_ic(count, drc_index); rc = dlpar_memory_remove_by_ic(count, drc_index);
break; break;
default: default:

View File

@ -121,7 +121,7 @@ int dlpar_hp_pmem(struct pseries_hp_errorlog *hp_elog)
return -EINVAL; return -EINVAL;
} }
drc_index = hp_elog->_drc_u.drc_index; drc_index = be32_to_cpu(hp_elog->_drc_u.drc_index);
lock_device_hotplug(); lock_device_hotplug();

View File

@ -216,6 +216,11 @@ config GENERIC_HWEIGHT
config FIX_EARLYCON_MEM config FIX_EARLYCON_MEM
def_bool MMU def_bool MMU
config ILLEGAL_POINTER_VALUE
hex
default 0 if 32BIT
default 0xdead000000000000 if 64BIT
config PGTABLE_LEVELS config PGTABLE_LEVELS
int int
default 5 if 64BIT default 5 if 64BIT

View File

@ -7,7 +7,7 @@
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
#define MAX_PHYSMEM_BITS 56 #define MAX_PHYSMEM_BITS 56
#else #else
#define MAX_PHYSMEM_BITS 34 #define MAX_PHYSMEM_BITS 32
#endif /* CONFIG_64BIT */ #endif /* CONFIG_64BIT */
#define SECTION_SIZE_BITS 27 #define SECTION_SIZE_BITS 27
#endif /* CONFIG_SPARSEMEM */ #endif /* CONFIG_SPARSEMEM */

View File

@ -444,6 +444,12 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
*(u32 *)loc = CLEAN_IMM(CJTYPE, *(u32 *)loc) | *(u32 *)loc = CLEAN_IMM(CJTYPE, *(u32 *)loc) |
ENCODE_CJTYPE_IMM(val - addr); ENCODE_CJTYPE_IMM(val - addr);
break; break;
case R_RISCV_ADD16:
*(u16 *)loc += val;
break;
case R_RISCV_SUB16:
*(u16 *)loc -= val;
break;
case R_RISCV_ADD32: case R_RISCV_ADD32:
*(u32 *)loc += val; *(u32 *)loc += val;
break; break;

View File

@ -62,7 +62,7 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
perf_callchain_store(entry, regs->epc); perf_callchain_store(entry, regs->epc);
fp = user_backtrace(entry, fp, regs->ra); fp = user_backtrace(entry, fp, regs->ra);
while (fp && !(fp & 0x3) && entry->nr < entry->max_stack) while (fp && !(fp & 0x7) && entry->nr < entry->max_stack)
fp = user_backtrace(entry, fp, 0); fp = user_backtrace(entry, fp, 0);
} }

View File

@ -67,8 +67,8 @@ void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run)
run->riscv_sbi.args[3] = cp->a3; run->riscv_sbi.args[3] = cp->a3;
run->riscv_sbi.args[4] = cp->a4; run->riscv_sbi.args[4] = cp->a4;
run->riscv_sbi.args[5] = cp->a5; run->riscv_sbi.args[5] = cp->a5;
run->riscv_sbi.ret[0] = cp->a0; run->riscv_sbi.ret[0] = SBI_ERR_NOT_SUPPORTED;
run->riscv_sbi.ret[1] = cp->a1; run->riscv_sbi.ret[1] = 0;
} }
void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu, void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu,

View File

@ -60,8 +60,10 @@ static inline int test_facility(unsigned long nr)
unsigned long facilities_als[] = { FACILITIES_ALS }; unsigned long facilities_als[] = { FACILITIES_ALS };
if (__builtin_constant_p(nr) && nr < sizeof(facilities_als) * 8) { if (__builtin_constant_p(nr) && nr < sizeof(facilities_als) * 8) {
if (__test_facility(nr, &facilities_als)) if (__test_facility(nr, &facilities_als)) {
return 1; if (!__is_defined(__DECOMPRESSOR))
return 1;
}
} }
return __test_facility(nr, &stfle_fac_list); return __test_facility(nr, &stfle_fac_list);
} }

View File

@ -1432,7 +1432,7 @@ static int aux_output_begin(struct perf_output_handle *handle,
unsigned long head, base, offset; unsigned long head, base, offset;
struct hws_trailer_entry *te; struct hws_trailer_entry *te;
if (WARN_ON_ONCE(handle->head & ~PAGE_MASK)) if (handle->head & ~PAGE_MASK)
return -EINVAL; return -EINVAL;
aux->head = handle->head >> PAGE_SHIFT; aux->head = handle->head >> PAGE_SHIFT;
@ -1613,7 +1613,7 @@ static void hw_collect_aux(struct cpu_hw_sf *cpuhw)
unsigned long num_sdb; unsigned long num_sdb;
aux = perf_get_aux(handle); aux = perf_get_aux(handle);
if (WARN_ON_ONCE(!aux)) if (!aux)
return; return;
/* Inform user space new data arrived */ /* Inform user space new data arrived */
@ -1635,7 +1635,7 @@ static void hw_collect_aux(struct cpu_hw_sf *cpuhw)
__func__); __func__);
break; break;
} }
if (WARN_ON_ONCE(!aux)) if (!aux)
return; return;
/* Update head and alert_mark to new position */ /* Update head and alert_mark to new position */
@ -1870,12 +1870,8 @@ static void cpumsf_pmu_start(struct perf_event *event, int flags)
{ {
struct cpu_hw_sf *cpuhw = this_cpu_ptr(&cpu_hw_sf); struct cpu_hw_sf *cpuhw = this_cpu_ptr(&cpu_hw_sf);
if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED))) if (!(event->hw.state & PERF_HES_STOPPED))
return; return;
if (flags & PERF_EF_RELOAD)
WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE));
perf_pmu_disable(event->pmu); perf_pmu_disable(event->pmu);
event->hw.state = 0; event->hw.state = 0;
cpuhw->lsctl.cs = 1; cpuhw->lsctl.cs = 1;

View File

@ -95,11 +95,12 @@ static long cmm_alloc_pages(long nr, long *counter,
(*counter)++; (*counter)++;
spin_unlock(&cmm_lock); spin_unlock(&cmm_lock);
nr--; nr--;
cond_resched();
} }
return nr; return nr;
} }
static long cmm_free_pages(long nr, long *counter, struct cmm_page_array **list) static long __cmm_free_pages(long nr, long *counter, struct cmm_page_array **list)
{ {
struct cmm_page_array *pa; struct cmm_page_array *pa;
unsigned long addr; unsigned long addr;
@ -123,6 +124,21 @@ static long cmm_free_pages(long nr, long *counter, struct cmm_page_array **list)
return nr; return nr;
} }
static long cmm_free_pages(long nr, long *counter, struct cmm_page_array **list)
{
long inc = 0;
while (nr) {
inc = min(256L, nr);
nr -= inc;
inc = __cmm_free_pages(inc, counter, list);
if (inc)
break;
cond_resched();
}
return nr + inc;
}
static int cmm_oom_notify(struct notifier_block *self, static int cmm_oom_notify(struct notifier_block *self,
unsigned long dummy, void *parm) unsigned long dummy, void *parm)
{ {

View File

@ -12,6 +12,7 @@
#include <asm/insn.h> #include <asm/insn.h>
#include <asm/insn-eval.h> #include <asm/insn-eval.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/traps.h>
/* TDX module Call Leaf IDs */ /* TDX module Call Leaf IDs */
#define TDX_GET_INFO 1 #define TDX_GET_INFO 1
@ -371,6 +372,11 @@ static int handle_mmio(struct pt_regs *regs, struct ve_info *ve)
return -EINVAL; return -EINVAL;
} }
if (!fault_in_kernel_space(ve->gla)) {
WARN_ONCE(1, "Access to userspace address is not supported");
return -EINVAL;
}
/* /*
* Reject EPT violation #VEs that split pages. * Reject EPT violation #VEs that split pages.
* *

View File

@ -41,6 +41,8 @@
#include <asm/desc.h> #include <asm/desc.h>
#include <asm/ldt.h> #include <asm/ldt.h>
#include <asm/unwind.h> #include <asm/unwind.h>
#include <asm/uprobes.h>
#include <asm/ibt.h>
#include "perf_event.h" #include "perf_event.h"
@ -2841,6 +2843,46 @@ static unsigned long get_segment_base(unsigned int segment)
return get_desc_base(desc); return get_desc_base(desc);
} }
#ifdef CONFIG_UPROBES
/*
* Heuristic-based check if uprobe is installed at the function entry.
*
* Under assumption of user code being compiled with frame pointers,
* `push %rbp/%ebp` is a good indicator that we indeed are.
*
* Similarly, `endbr64` (assuming 64-bit mode) is also a common pattern.
* If we get this wrong, captured stack trace might have one extra bogus
* entry, but the rest of stack trace will still be meaningful.
*/
static bool is_uprobe_at_func_entry(struct pt_regs *regs)
{
struct arch_uprobe *auprobe;
if (!current->utask)
return false;
auprobe = current->utask->auprobe;
if (!auprobe)
return false;
/* push %rbp/%ebp */
if (auprobe->insn[0] == 0x55)
return true;
/* endbr64 (64-bit only) */
if (user_64bit_mode(regs) && is_endbr(*(u32 *)auprobe->insn))
return true;
return false;
}
#else
static bool is_uprobe_at_func_entry(struct pt_regs *regs)
{
return false;
}
#endif /* CONFIG_UPROBES */
#ifdef CONFIG_IA32_EMULATION #ifdef CONFIG_IA32_EMULATION
#include <linux/compat.h> #include <linux/compat.h>
@ -2852,6 +2894,7 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *ent
unsigned long ss_base, cs_base; unsigned long ss_base, cs_base;
struct stack_frame_ia32 frame; struct stack_frame_ia32 frame;
const struct stack_frame_ia32 __user *fp; const struct stack_frame_ia32 __user *fp;
u32 ret_addr;
if (user_64bit_mode(regs)) if (user_64bit_mode(regs))
return 0; return 0;
@ -2861,6 +2904,12 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *ent
fp = compat_ptr(ss_base + regs->bp); fp = compat_ptr(ss_base + regs->bp);
pagefault_disable(); pagefault_disable();
/* see perf_callchain_user() below for why we do this */
if (is_uprobe_at_func_entry(regs) &&
!get_user(ret_addr, (const u32 __user *)regs->sp))
perf_callchain_store(entry, ret_addr);
while (entry->nr < entry->max_stack) { while (entry->nr < entry->max_stack) {
if (!valid_user_frame(fp, sizeof(frame))) if (!valid_user_frame(fp, sizeof(frame)))
break; break;
@ -2889,6 +2938,7 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs
{ {
struct stack_frame frame; struct stack_frame frame;
const struct stack_frame __user *fp; const struct stack_frame __user *fp;
unsigned long ret_addr;
if (perf_guest_state()) { if (perf_guest_state()) {
/* TODO: We don't support guest os callchain now */ /* TODO: We don't support guest os callchain now */
@ -2912,6 +2962,19 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs
return; return;
pagefault_disable(); pagefault_disable();
/*
* If we are called from uprobe handler, and we are indeed at the very
* entry to user function (which is normally a `push %rbp` instruction,
* under assumption of application being compiled with frame pointers),
* we should read return address from *regs->sp before proceeding
* to follow frame pointers, otherwise we'll skip immediate caller
* as %rbp is not yet setup.
*/
if (is_uprobe_at_func_entry(regs) &&
!get_user(ret_addr, (const unsigned long __user *)regs->sp))
perf_callchain_store(entry, ret_addr);
while (entry->nr < entry->max_stack) { while (entry->nr < entry->max_stack) {
if (!valid_user_frame(fp, sizeof(frame))) if (!valid_user_frame(fp, sizeof(frame)))
break; break;

View File

@ -1602,6 +1602,7 @@ static void pt_event_stop(struct perf_event *event, int mode)
* see comment in intel_pt_interrupt(). * see comment in intel_pt_interrupt().
*/ */
WRITE_ONCE(pt->handle_nmi, 0); WRITE_ONCE(pt->handle_nmi, 0);
barrier();
pt_config_stop(event); pt_config_stop(event);
@ -1653,11 +1654,10 @@ static long pt_event_snapshot_aux(struct perf_event *event,
return 0; return 0;
/* /*
* Here, handle_nmi tells us if the tracing is on * There is no PT interrupt in this mode, so stop the trace and it will
* remain stopped while the buffer is copied.
*/ */
if (READ_ONCE(pt->handle_nmi)) pt_config_stop(event);
pt_config_stop(event);
pt_read_offset(buf); pt_read_offset(buf);
pt_update_head(pt); pt_update_head(pt);
@ -1669,11 +1669,10 @@ static long pt_event_snapshot_aux(struct perf_event *event,
ret = perf_output_copy_aux(&pt->handle, handle, from, to); ret = perf_output_copy_aux(&pt->handle, handle, from, to);
/* /*
* If the tracing was on when we turned up, restart it. * Here, handle_nmi tells us if the tracing was on.
* Compiler barrier not needed as we couldn't have been * If the tracing was on, restart it.
* preempted by anything that touches pt->handle_nmi.
*/ */
if (pt->handle_nmi) if (READ_ONCE(pt->handle_nmi))
pt_config_start(event); pt_config_start(event);
return ret; return ret;

View File

@ -62,7 +62,11 @@ extern u64 arch_irq_stat(void);
#if IS_ENABLED(CONFIG_KVM_INTEL) #if IS_ENABLED(CONFIG_KVM_INTEL)
static inline void kvm_set_cpu_l1tf_flush_l1d(void) /*
* This function is called from noinstr interrupt contexts
* and must be inlined to not get instrumentation.
*/
static __always_inline void kvm_set_cpu_l1tf_flush_l1d(void)
{ {
__this_cpu_write(irq_stat.kvm_cpu_l1tf_flush_l1d, 1); __this_cpu_write(irq_stat.kvm_cpu_l1tf_flush_l1d, 1);
} }
@ -77,7 +81,7 @@ static __always_inline bool kvm_get_cpu_l1tf_flush_l1d(void)
return __this_cpu_read(irq_stat.kvm_cpu_l1tf_flush_l1d); return __this_cpu_read(irq_stat.kvm_cpu_l1tf_flush_l1d);
} }
#else /* !IS_ENABLED(CONFIG_KVM_INTEL) */ #else /* !IS_ENABLED(CONFIG_KVM_INTEL) */
static inline void kvm_set_cpu_l1tf_flush_l1d(void) { } static __always_inline void kvm_set_cpu_l1tf_flush_l1d(void) { }
#endif /* IS_ENABLED(CONFIG_KVM_INTEL) */ #endif /* IS_ENABLED(CONFIG_KVM_INTEL) */
#endif /* _ASM_X86_HARDIRQ_H */ #endif /* _ASM_X86_HARDIRQ_H */

View File

@ -13,15 +13,18 @@
#include <asm/irq_stack.h> #include <asm/irq_stack.h>
typedef void (*idtentry_t)(struct pt_regs *regs);
/** /**
* DECLARE_IDTENTRY - Declare functions for simple IDT entry points * DECLARE_IDTENTRY - Declare functions for simple IDT entry points
* No error code pushed by hardware * No error code pushed by hardware
* @vector: Vector number (ignored for C) * @vector: Vector number (ignored for C)
* @func: Function name of the entry point * @func: Function name of the entry point
* *
* Declares three functions: * Declares four functions:
* - The ASM entry point: asm_##func * - The ASM entry point: asm_##func
* - The XEN PV trap entry point: xen_##func (maybe unused) * - The XEN PV trap entry point: xen_##func (maybe unused)
* - The C handler called from the FRED event dispatcher (maybe unused)
* - The C handler called from the ASM entry point * - The C handler called from the ASM entry point
* *
* Note: This is the C variant of DECLARE_IDTENTRY(). As the name says it * Note: This is the C variant of DECLARE_IDTENTRY(). As the name says it
@ -31,6 +34,7 @@
#define DECLARE_IDTENTRY(vector, func) \ #define DECLARE_IDTENTRY(vector, func) \
asmlinkage void asm_##func(void); \ asmlinkage void asm_##func(void); \
asmlinkage void xen_asm_##func(void); \ asmlinkage void xen_asm_##func(void); \
void fred_##func(struct pt_regs *regs); \
__visible void func(struct pt_regs *regs) __visible void func(struct pt_regs *regs)
/** /**
@ -137,6 +141,17 @@ static __always_inline void __##func(struct pt_regs *regs, \
#define DEFINE_IDTENTRY_RAW(func) \ #define DEFINE_IDTENTRY_RAW(func) \
__visible noinstr void func(struct pt_regs *regs) __visible noinstr void func(struct pt_regs *regs)
/**
* DEFINE_FREDENTRY_RAW - Emit code for raw FRED entry points
* @func: Function name of the entry point
*
* @func is called from the FRED event dispatcher with interrupts disabled.
*
* See @DEFINE_IDTENTRY_RAW for further details.
*/
#define DEFINE_FREDENTRY_RAW(func) \
noinstr void fred_##func(struct pt_regs *regs)
/** /**
* DECLARE_IDTENTRY_RAW_ERRORCODE - Declare functions for raw IDT entry points * DECLARE_IDTENTRY_RAW_ERRORCODE - Declare functions for raw IDT entry points
* Error code pushed by hardware * Error code pushed by hardware
@ -197,8 +212,8 @@ __visible noinstr void func(struct pt_regs *regs, \
irqentry_state_t state = irqentry_enter(regs); \ irqentry_state_t state = irqentry_enter(regs); \
u32 vector = (u32)(u8)error_code; \ u32 vector = (u32)(u8)error_code; \
\ \
kvm_set_cpu_l1tf_flush_l1d(); \
instrumentation_begin(); \ instrumentation_begin(); \
kvm_set_cpu_l1tf_flush_l1d(); \
run_irq_on_irqstack_cond(__##func, regs, vector); \ run_irq_on_irqstack_cond(__##func, regs, vector); \
instrumentation_end(); \ instrumentation_end(); \
irqentry_exit(regs, state); \ irqentry_exit(regs, state); \
@ -233,17 +248,27 @@ static noinline void __##func(struct pt_regs *regs, u32 vector)
#define DEFINE_IDTENTRY_SYSVEC(func) \ #define DEFINE_IDTENTRY_SYSVEC(func) \
static void __##func(struct pt_regs *regs); \ static void __##func(struct pt_regs *regs); \
\ \
static __always_inline void instr_##func(struct pt_regs *regs) \
{ \
run_sysvec_on_irqstack_cond(__##func, regs); \
} \
\
__visible noinstr void func(struct pt_regs *regs) \ __visible noinstr void func(struct pt_regs *regs) \
{ \ { \
irqentry_state_t state = irqentry_enter(regs); \ irqentry_state_t state = irqentry_enter(regs); \
\ \
kvm_set_cpu_l1tf_flush_l1d(); \
instrumentation_begin(); \ instrumentation_begin(); \
kvm_set_cpu_l1tf_flush_l1d(); \ instr_##func (regs); \
run_sysvec_on_irqstack_cond(__##func, regs); \
instrumentation_end(); \ instrumentation_end(); \
irqentry_exit(regs, state); \ irqentry_exit(regs, state); \
} \ } \
\ \
void fred_##func(struct pt_regs *regs) \
{ \
instr_##func (regs); \
} \
\
static noinline void __##func(struct pt_regs *regs) static noinline void __##func(struct pt_regs *regs)
/** /**
@ -260,19 +285,29 @@ static noinline void __##func(struct pt_regs *regs)
#define DEFINE_IDTENTRY_SYSVEC_SIMPLE(func) \ #define DEFINE_IDTENTRY_SYSVEC_SIMPLE(func) \
static __always_inline void __##func(struct pt_regs *regs); \ static __always_inline void __##func(struct pt_regs *regs); \
\ \
static __always_inline void instr_##func(struct pt_regs *regs) \
{ \
__irq_enter_raw(); \
__##func (regs); \
__irq_exit_raw(); \
} \
\
__visible noinstr void func(struct pt_regs *regs) \ __visible noinstr void func(struct pt_regs *regs) \
{ \ { \
irqentry_state_t state = irqentry_enter(regs); \ irqentry_state_t state = irqentry_enter(regs); \
\ \
kvm_set_cpu_l1tf_flush_l1d(); \
instrumentation_begin(); \ instrumentation_begin(); \
__irq_enter_raw(); \ instr_##func (regs); \
kvm_set_cpu_l1tf_flush_l1d(); \
__##func (regs); \
__irq_exit_raw(); \
instrumentation_end(); \ instrumentation_end(); \
irqentry_exit(regs, state); \ irqentry_exit(regs, state); \
} \ } \
\ \
void fred_##func(struct pt_regs *regs) \
{ \
instr_##func (regs); \
} \
\
static __always_inline void __##func(struct pt_regs *regs) static __always_inline void __##func(struct pt_regs *regs)
/** /**
@ -410,15 +445,18 @@ __visible noinstr void func(struct pt_regs *regs, \
/* C-Code mapping */ /* C-Code mapping */
#define DECLARE_IDTENTRY_NMI DECLARE_IDTENTRY_RAW #define DECLARE_IDTENTRY_NMI DECLARE_IDTENTRY_RAW
#define DEFINE_IDTENTRY_NMI DEFINE_IDTENTRY_RAW #define DEFINE_IDTENTRY_NMI DEFINE_IDTENTRY_RAW
#define DEFINE_FREDENTRY_NMI DEFINE_FREDENTRY_RAW
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
#define DECLARE_IDTENTRY_MCE DECLARE_IDTENTRY_IST #define DECLARE_IDTENTRY_MCE DECLARE_IDTENTRY_IST
#define DEFINE_IDTENTRY_MCE DEFINE_IDTENTRY_IST #define DEFINE_IDTENTRY_MCE DEFINE_IDTENTRY_IST
#define DEFINE_IDTENTRY_MCE_USER DEFINE_IDTENTRY_NOIST #define DEFINE_IDTENTRY_MCE_USER DEFINE_IDTENTRY_NOIST
#define DEFINE_FREDENTRY_MCE DEFINE_FREDENTRY_RAW
#define DECLARE_IDTENTRY_DEBUG DECLARE_IDTENTRY_IST #define DECLARE_IDTENTRY_DEBUG DECLARE_IDTENTRY_IST
#define DEFINE_IDTENTRY_DEBUG DEFINE_IDTENTRY_IST #define DEFINE_IDTENTRY_DEBUG DEFINE_IDTENTRY_IST
#define DEFINE_IDTENTRY_DEBUG_USER DEFINE_IDTENTRY_NOIST #define DEFINE_IDTENTRY_DEBUG_USER DEFINE_IDTENTRY_NOIST
#define DEFINE_FREDENTRY_DEBUG DEFINE_FREDENTRY_RAW
#endif #endif
#else /* !__ASSEMBLY__ */ #else /* !__ASSEMBLY__ */
@ -660,23 +698,36 @@ DECLARE_IDTENTRY_SYSVEC(IRQ_MOVE_CLEANUP_VECTOR, sysvec_irq_move_cleanup);
DECLARE_IDTENTRY_SYSVEC(REBOOT_VECTOR, sysvec_reboot); DECLARE_IDTENTRY_SYSVEC(REBOOT_VECTOR, sysvec_reboot);
DECLARE_IDTENTRY_SYSVEC(CALL_FUNCTION_SINGLE_VECTOR, sysvec_call_function_single); DECLARE_IDTENTRY_SYSVEC(CALL_FUNCTION_SINGLE_VECTOR, sysvec_call_function_single);
DECLARE_IDTENTRY_SYSVEC(CALL_FUNCTION_VECTOR, sysvec_call_function); DECLARE_IDTENTRY_SYSVEC(CALL_FUNCTION_VECTOR, sysvec_call_function);
#else
# define fred_sysvec_reschedule_ipi NULL
# define fred_sysvec_reboot NULL
# define fred_sysvec_call_function_single NULL
# define fred_sysvec_call_function NULL
#endif #endif
#ifdef CONFIG_X86_LOCAL_APIC #ifdef CONFIG_X86_LOCAL_APIC
# ifdef CONFIG_X86_MCE_THRESHOLD # ifdef CONFIG_X86_MCE_THRESHOLD
DECLARE_IDTENTRY_SYSVEC(THRESHOLD_APIC_VECTOR, sysvec_threshold); DECLARE_IDTENTRY_SYSVEC(THRESHOLD_APIC_VECTOR, sysvec_threshold);
# else
# define fred_sysvec_threshold NULL
# endif # endif
# ifdef CONFIG_X86_MCE_AMD # ifdef CONFIG_X86_MCE_AMD
DECLARE_IDTENTRY_SYSVEC(DEFERRED_ERROR_VECTOR, sysvec_deferred_error); DECLARE_IDTENTRY_SYSVEC(DEFERRED_ERROR_VECTOR, sysvec_deferred_error);
# else
# define fred_sysvec_deferred_error NULL
# endif # endif
# ifdef CONFIG_X86_THERMAL_VECTOR # ifdef CONFIG_X86_THERMAL_VECTOR
DECLARE_IDTENTRY_SYSVEC(THERMAL_APIC_VECTOR, sysvec_thermal); DECLARE_IDTENTRY_SYSVEC(THERMAL_APIC_VECTOR, sysvec_thermal);
# else
# define fred_sysvec_thermal NULL
# endif # endif
# ifdef CONFIG_IRQ_WORK # ifdef CONFIG_IRQ_WORK
DECLARE_IDTENTRY_SYSVEC(IRQ_WORK_VECTOR, sysvec_irq_work); DECLARE_IDTENTRY_SYSVEC(IRQ_WORK_VECTOR, sysvec_irq_work);
# else
# define fred_sysvec_irq_work NULL
# endif # endif
#endif #endif
@ -684,12 +735,16 @@ DECLARE_IDTENTRY_SYSVEC(IRQ_WORK_VECTOR, sysvec_irq_work);
DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_VECTOR, sysvec_kvm_posted_intr_ipi); DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_VECTOR, sysvec_kvm_posted_intr_ipi);
DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_WAKEUP_VECTOR, sysvec_kvm_posted_intr_wakeup_ipi); DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_WAKEUP_VECTOR, sysvec_kvm_posted_intr_wakeup_ipi);
DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_NESTED_VECTOR, sysvec_kvm_posted_intr_nested_ipi); DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_NESTED_VECTOR, sysvec_kvm_posted_intr_nested_ipi);
#else
# define fred_sysvec_kvm_posted_intr_ipi NULL
# define fred_sysvec_kvm_posted_intr_wakeup_ipi NULL
# define fred_sysvec_kvm_posted_intr_nested_ipi NULL
#endif #endif
#if IS_ENABLED(CONFIG_HYPERV) #if IS_ENABLED(CONFIG_HYPERV)
DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_CALLBACK_VECTOR, sysvec_hyperv_callback); DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_CALLBACK_VECTOR, sysvec_hyperv_callback);
DECLARE_IDTENTRY_SYSVEC(HYPERV_REENLIGHTENMENT_VECTOR, sysvec_hyperv_reenlightenment); DECLARE_IDTENTRY_SYSVEC(HYPERV_REENLIGHTENMENT_VECTOR, sysvec_hyperv_reenlightenment);
DECLARE_IDTENTRY_SYSVEC(HYPERV_STIMER0_VECTOR, sysvec_hyperv_stimer0); DECLARE_IDTENTRY_SYSVEC(HYPERV_STIMER0_VECTOR, sysvec_hyperv_stimer0);
#endif #endif
#if IS_ENABLED(CONFIG_ACRN_GUEST) #if IS_ENABLED(CONFIG_ACRN_GUEST)

View File

@ -82,7 +82,12 @@ static inline void syscall_get_arguments(struct task_struct *task,
struct pt_regs *regs, struct pt_regs *regs,
unsigned long *args) unsigned long *args)
{ {
memcpy(args, &regs->bx, 6 * sizeof(args[0])); args[0] = regs->bx;
args[1] = regs->cx;
args[2] = regs->dx;
args[3] = regs->si;
args[4] = regs->di;
args[5] = regs->bp;
} }
static inline int syscall_get_arch(struct task_struct *task) static inline int syscall_get_arch(struct task_struct *task)

View File

@ -351,27 +351,26 @@ static void ioapic_mask_entry(int apic, int pin)
* shared ISA-space IRQs, so we have to support them. We are super * shared ISA-space IRQs, so we have to support them. We are super
* fast in the common case, and fast for shared ISA-space IRQs. * fast in the common case, and fast for shared ISA-space IRQs.
*/ */
static int __add_pin_to_irq_node(struct mp_chip_data *data, static bool add_pin_to_irq_node(struct mp_chip_data *data, int node, int apic, int pin)
int node, int apic, int pin)
{ {
struct irq_pin_list *entry; struct irq_pin_list *entry;
/* don't allow duplicates */ /* Don't allow duplicates */
for_each_irq_pin(entry, data->irq_2_pin) for_each_irq_pin(entry, data->irq_2_pin) {
if (entry->apic == apic && entry->pin == pin) if (entry->apic == apic && entry->pin == pin)
return 0; return true;
}
entry = kzalloc_node(sizeof(struct irq_pin_list), GFP_ATOMIC, node); entry = kzalloc_node(sizeof(struct irq_pin_list), GFP_ATOMIC, node);
if (!entry) { if (!entry) {
pr_err("can not alloc irq_pin_list (%d,%d,%d)\n", pr_err("Cannot allocate irq_pin_list (%d,%d,%d)\n", node, apic, pin);
node, apic, pin); return false;
return -ENOMEM;
} }
entry->apic = apic; entry->apic = apic;
entry->pin = pin; entry->pin = pin;
list_add_tail(&entry->list, &data->irq_2_pin); list_add_tail(&entry->list, &data->irq_2_pin);
return true;
return 0;
} }
static void __remove_pin_from_irq(struct mp_chip_data *data, int apic, int pin) static void __remove_pin_from_irq(struct mp_chip_data *data, int apic, int pin)
@ -386,13 +385,6 @@ static void __remove_pin_from_irq(struct mp_chip_data *data, int apic, int pin)
} }
} }
static void add_pin_to_irq_node(struct mp_chip_data *data,
int node, int apic, int pin)
{
if (__add_pin_to_irq_node(data, node, apic, pin))
panic("IO-APIC: failed to add irq-pin. Can not proceed\n");
}
/* /*
* Reroute an IRQ to a different pin. * Reroute an IRQ to a different pin.
*/ */
@ -1001,8 +993,7 @@ static int alloc_isa_irq_from_domain(struct irq_domain *domain,
if (irq_data && irq_data->parent_data) { if (irq_data && irq_data->parent_data) {
if (!mp_check_pin_attr(irq, info)) if (!mp_check_pin_attr(irq, info))
return -EBUSY; return -EBUSY;
if (__add_pin_to_irq_node(irq_data->chip_data, node, ioapic, if (!add_pin_to_irq_node(irq_data->chip_data, node, ioapic, info->ioapic.pin))
info->ioapic.pin))
return -ENOMEM; return -ENOMEM;
} else { } else {
info->flags |= X86_IRQ_ALLOC_LEGACY; info->flags |= X86_IRQ_ALLOC_LEGACY;
@ -3038,10 +3029,8 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq,
return -ENOMEM; return -ENOMEM;
ret = irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, info); ret = irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, info);
if (ret < 0) { if (ret < 0)
kfree(data); goto free_data;
return ret;
}
INIT_LIST_HEAD(&data->irq_2_pin); INIT_LIST_HEAD(&data->irq_2_pin);
irq_data->hwirq = info->ioapic.pin; irq_data->hwirq = info->ioapic.pin;
@ -3050,7 +3039,10 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq,
irq_data->chip_data = data; irq_data->chip_data = data;
mp_irqdomain_get_attr(mp_pin_to_gsi(ioapic, pin), data, info); mp_irqdomain_get_attr(mp_pin_to_gsi(ioapic, pin), data, info);
add_pin_to_irq_node(data, ioapic_alloc_attr_node(info), ioapic, pin); if (!add_pin_to_irq_node(data, ioapic_alloc_attr_node(info), ioapic, pin)) {
ret = -ENOMEM;
goto free_irqs;
}
mp_preconfigure_entry(data); mp_preconfigure_entry(data);
mp_register_handler(virq, data->is_level); mp_register_handler(virq, data->is_level);
@ -3065,6 +3057,12 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq,
ioapic, mpc_ioapic_id(ioapic), pin, virq, ioapic, mpc_ioapic_id(ioapic), pin, virq,
data->is_level, data->active_low); data->is_level, data->active_low);
return 0; return 0;
free_irqs:
irq_domain_free_irqs_parent(domain, virq, nr_irqs);
free_data:
kfree(data);
return ret;
} }
void mp_irqdomain_free(struct irq_domain *domain, unsigned int virq, void mp_irqdomain_free(struct irq_domain *domain, unsigned int virq,

View File

@ -474,24 +474,25 @@ struct sgx_epc_page *__sgx_alloc_epc_page(void)
{ {
struct sgx_epc_page *page; struct sgx_epc_page *page;
int nid_of_current = numa_node_id(); int nid_of_current = numa_node_id();
int nid = nid_of_current; int nid_start, nid;
if (node_isset(nid_of_current, sgx_numa_mask)) { /*
page = __sgx_alloc_epc_page_from_node(nid_of_current); * Try local node first. If it doesn't have an EPC section,
if (page) * fall back to the non-local NUMA nodes.
return page; */
} if (node_isset(nid_of_current, sgx_numa_mask))
nid_start = nid_of_current;
/* Fall back to the non-local NUMA nodes: */ else
while (true) { nid_start = next_node_in(nid_of_current, sgx_numa_mask);
nid = next_node_in(nid, sgx_numa_mask);
if (nid == nid_of_current)
break;
nid = nid_start;
do {
page = __sgx_alloc_epc_page_from_node(nid); page = __sgx_alloc_epc_page_from_node(nid);
if (page) if (page)
return page; return page;
}
nid = next_node_in(nid, sgx_numa_mask);
} while (nid != nid_start);
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
} }

View File

@ -28,6 +28,7 @@
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/set_memory.h> #include <asm/set_memory.h>
#include <asm/cpu.h> #include <asm/cpu.h>
#include <asm/efi.h>
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
/* /*
@ -90,6 +91,8 @@ map_efi_systab(struct x86_mapping_info *info, pgd_t *level4p)
{ {
#ifdef CONFIG_EFI #ifdef CONFIG_EFI
unsigned long mstart, mend; unsigned long mstart, mend;
void *kaddr;
int ret;
if (!efi_enabled(EFI_BOOT)) if (!efi_enabled(EFI_BOOT))
return 0; return 0;
@ -105,6 +108,30 @@ map_efi_systab(struct x86_mapping_info *info, pgd_t *level4p)
if (!mstart) if (!mstart)
return 0; return 0;
ret = kernel_ident_mapping_init(info, level4p, mstart, mend);
if (ret)
return ret;
kaddr = memremap(mstart, mend - mstart, MEMREMAP_WB);
if (!kaddr) {
pr_err("Could not map UEFI system table\n");
return -ENOMEM;
}
mstart = efi_config_table;
if (efi_enabled(EFI_64BIT)) {
efi_system_table_64_t *stbl = (efi_system_table_64_t *)kaddr;
mend = mstart + sizeof(efi_config_table_64_t) * stbl->nr_tables;
} else {
efi_system_table_32_t *stbl = (efi_system_table_32_t *)kaddr;
mend = mstart + sizeof(efi_config_table_32_t) * stbl->nr_tables;
}
memunmap(kaddr);
return kernel_ident_mapping_init(info, level4p, mstart, mend); return kernel_ident_mapping_init(info, level4p, mstart, mend);
#endif #endif
return 0; return 0;

View File

@ -2297,6 +2297,29 @@ void kvm_lapic_set_eoi(struct kvm_vcpu *vcpu)
} }
EXPORT_SYMBOL_GPL(kvm_lapic_set_eoi); EXPORT_SYMBOL_GPL(kvm_lapic_set_eoi);
#define X2APIC_ICR_RESERVED_BITS (GENMASK_ULL(31, 20) | GENMASK_ULL(17, 16) | BIT(13))
int kvm_x2apic_icr_write(struct kvm_lapic *apic, u64 data)
{
if (data & X2APIC_ICR_RESERVED_BITS)
return 1;
/*
* The BUSY bit is reserved on both Intel and AMD in x2APIC mode, but
* only AMD requires it to be zero, Intel essentially just ignores the
* bit. And if IPI virtualization (Intel) or x2AVIC (AMD) is enabled,
* the CPU performs the reserved bits checks, i.e. the underlying CPU
* behavior will "win". Arbitrarily clear the BUSY bit, as there is no
* sane way to provide consistent behavior with respect to hardware.
*/
data &= ~APIC_ICR_BUSY;
kvm_apic_send_ipi(apic, (u32)data, (u32)(data >> 32));
kvm_lapic_set_reg64(apic, APIC_ICR, data);
trace_kvm_apic_write(APIC_ICR, data);
return 0;
}
/* emulate APIC access in a trap manner */ /* emulate APIC access in a trap manner */
void kvm_apic_write_nodecode(struct kvm_vcpu *vcpu, u32 offset) void kvm_apic_write_nodecode(struct kvm_vcpu *vcpu, u32 offset)
{ {
@ -2314,7 +2337,7 @@ void kvm_apic_write_nodecode(struct kvm_vcpu *vcpu, u32 offset)
* maybe-unecessary write, and both are in the noise anyways. * maybe-unecessary write, and both are in the noise anyways.
*/ */
if (apic_x2apic_mode(apic) && offset == APIC_ICR) if (apic_x2apic_mode(apic) && offset == APIC_ICR)
kvm_x2apic_icr_write(apic, kvm_lapic_get_reg64(apic, APIC_ICR)); WARN_ON_ONCE(kvm_x2apic_icr_write(apic, kvm_lapic_get_reg64(apic, APIC_ICR)));
else else
kvm_lapic_reg_write(apic, offset, kvm_lapic_get_reg(apic, offset)); kvm_lapic_reg_write(apic, offset, kvm_lapic_get_reg(apic, offset));
} }
@ -2936,16 +2959,6 @@ int kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr)
return 0; return 0;
} }
int kvm_x2apic_icr_write(struct kvm_lapic *apic, u64 data)
{
data &= ~APIC_ICR_BUSY;
kvm_apic_send_ipi(apic, (u32)data, (u32)(data >> 32));
kvm_lapic_set_reg64(apic, APIC_ICR, data);
trace_kvm_apic_write(APIC_ICR, data);
return 0;
}
static int kvm_lapic_msr_read(struct kvm_lapic *apic, u32 reg, u64 *data) static int kvm_lapic_msr_read(struct kvm_lapic *apic, u32 reg, u64 *data)
{ {
u32 low; u32 low;

View File

@ -57,6 +57,56 @@ static bool is_imm8(int value)
return value <= 127 && value >= -128; return value <= 127 && value >= -128;
} }
/*
* Let us limit the positive offset to be <= 123.
* This is to ensure eventual jit convergence For the following patterns:
* ...
* pass4, final_proglen=4391:
* ...
* 20e: 48 85 ff test rdi,rdi
* 211: 74 7d je 0x290
* 213: 48 8b 77 00 mov rsi,QWORD PTR [rdi+0x0]
* ...
* 289: 48 85 ff test rdi,rdi
* 28c: 74 17 je 0x2a5
* 28e: e9 7f ff ff ff jmp 0x212
* 293: bf 03 00 00 00 mov edi,0x3
* Note that insn at 0x211 is 2-byte cond jump insn for offset 0x7d (-125)
* and insn at 0x28e is 5-byte jmp insn with offset -129.
*
* pass5, final_proglen=4392:
* ...
* 20e: 48 85 ff test rdi,rdi
* 211: 0f 84 80 00 00 00 je 0x297
* 217: 48 8b 77 00 mov rsi,QWORD PTR [rdi+0x0]
* ...
* 28d: 48 85 ff test rdi,rdi
* 290: 74 1a je 0x2ac
* 292: eb 84 jmp 0x218
* 294: bf 03 00 00 00 mov edi,0x3
* Note that insn at 0x211 is 6-byte cond jump insn now since its offset
* becomes 0x80 based on previous round (0x293 - 0x213 = 0x80).
* At the same time, insn at 0x292 is a 2-byte insn since its offset is
* -124.
*
* pass6 will repeat the same code as in pass4 and this will prevent
* eventual convergence.
*
* To fix this issue, we need to break je (2->6 bytes) <-> jmp (5->2 bytes)
* cycle in the above. In the above example je offset <= 0x7c should work.
*
* For other cases, je <-> je needs offset <= 0x7b to avoid no convergence
* issue. For jmp <-> je and jmp <-> jmp cases, jmp offset <= 0x7c should
* avoid no convergence issue.
*
* Overall, let us limit the positive offset for 8bit cond/uncond jmp insn
* to maximum 123 (0x7b). This way, the jit pass can eventually converge.
*/
static bool is_imm8_jmp_offset(int value)
{
return value <= 123 && value >= -128;
}
static bool is_simm32(s64 value) static bool is_simm32(s64 value)
{ {
return value == (s64)(s32)value; return value == (s64)(s32)value;
@ -1589,7 +1639,7 @@ emit_cond_jmp: /* Convert BPF opcode to x86 */
return -EFAULT; return -EFAULT;
} }
jmp_offset = addrs[i + insn->off] - addrs[i]; jmp_offset = addrs[i + insn->off] - addrs[i];
if (is_imm8(jmp_offset)) { if (is_imm8_jmp_offset(jmp_offset)) {
if (jmp_padding) { if (jmp_padding) {
/* To keep the jmp_offset valid, the extra bytes are /* To keep the jmp_offset valid, the extra bytes are
* padded before the jump insn, so we subtract the * padded before the jump insn, so we subtract the
@ -1671,7 +1721,7 @@ emit_cond_jmp: /* Convert BPF opcode to x86 */
break; break;
} }
emit_jmp: emit_jmp:
if (is_imm8(jmp_offset)) { if (is_imm8_jmp_offset(jmp_offset)) {
if (jmp_padding) { if (jmp_padding) {
/* To avoid breaking jmp_offset, the extra bytes /* To avoid breaking jmp_offset, the extra bytes
* are padded before the actual jmp insn, so * are padded before the actual jmp insn, so

View File

@ -853,7 +853,7 @@ char * __init xen_memory_setup(void)
* to relocating (and even reusing) pages with kernel text or data. * to relocating (and even reusing) pages with kernel text or data.
*/ */
if (xen_is_e820_reserved(__pa_symbol(_text), if (xen_is_e820_reserved(__pa_symbol(_text),
__pa_symbol(__bss_stop) - __pa_symbol(_text))) { __pa_symbol(_end) - __pa_symbol(_text))) {
xen_raw_console_write("Xen hypervisor allocated kernel memory conflicts with E820 map\n"); xen_raw_console_write("Xen hypervisor allocated kernel memory conflicts with E820 map\n");
BUG(); BUG();
} }

View File

@ -2889,8 +2889,12 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
struct bfq_queue *in_service_bfqq, *new_bfqq; struct bfq_queue *in_service_bfqq, *new_bfqq;
/* if a merge has already been setup, then proceed with that first */ /* if a merge has already been setup, then proceed with that first */
if (bfqq->new_bfqq) new_bfqq = bfqq->new_bfqq;
return bfqq->new_bfqq; if (new_bfqq) {
while (new_bfqq->new_bfqq)
new_bfqq = new_bfqq->new_bfqq;
return new_bfqq;
}
/* /*
* Check delayed stable merge for rotational or non-queueing * Check delayed stable merge for rotational or non-queueing
@ -6624,7 +6628,7 @@ bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq)
{ {
bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue"); bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue");
if (bfqq_process_refs(bfqq) == 1) { if (bfqq_process_refs(bfqq) == 1 && !bfqq->new_bfqq) {
bfqq->pid = current->pid; bfqq->pid = current->pid;
bfq_clear_bfqq_coop(bfqq); bfq_clear_bfqq_coop(bfqq);
bfq_clear_bfqq_split_coop(bfqq); bfq_clear_bfqq_split_coop(bfqq);
@ -6720,6 +6724,31 @@ static void bfq_prepare_request(struct request *rq)
rq->elv.priv[0] = rq->elv.priv[1] = NULL; rq->elv.priv[0] = rq->elv.priv[1] = NULL;
} }
static struct bfq_queue *bfq_waker_bfqq(struct bfq_queue *bfqq)
{
struct bfq_queue *new_bfqq = bfqq->new_bfqq;
struct bfq_queue *waker_bfqq = bfqq->waker_bfqq;
if (!waker_bfqq)
return NULL;
while (new_bfqq) {
if (new_bfqq == waker_bfqq) {
/*
* If waker_bfqq is in the merge chain, and current
* is the only procress.
*/
if (bfqq_process_refs(waker_bfqq) == 1)
return NULL;
break;
}
new_bfqq = new_bfqq->new_bfqq;
}
return waker_bfqq;
}
/* /*
* If needed, init rq, allocate bfq data structures associated with * If needed, init rq, allocate bfq data structures associated with
* rq, and increment reference counters in the destination bfq_queue * rq, and increment reference counters in the destination bfq_queue
@ -6780,7 +6809,7 @@ static struct bfq_queue *bfq_init_rq(struct request *rq)
/* If the queue was seeky for too long, break it apart. */ /* If the queue was seeky for too long, break it apart. */
if (bfq_bfqq_coop(bfqq) && bfq_bfqq_split_coop(bfqq) && if (bfq_bfqq_coop(bfqq) && bfq_bfqq_split_coop(bfqq) &&
!bic->stably_merged) { !bic->stably_merged) {
struct bfq_queue *old_bfqq = bfqq; struct bfq_queue *waker_bfqq = bfq_waker_bfqq(bfqq);
/* Update bic before losing reference to bfqq */ /* Update bic before losing reference to bfqq */
if (bfq_bfqq_in_large_burst(bfqq)) if (bfq_bfqq_in_large_burst(bfqq))
@ -6799,7 +6828,7 @@ static struct bfq_queue *bfq_init_rq(struct request *rq)
bfqq_already_existing = true; bfqq_already_existing = true;
if (!bfqq_already_existing) { if (!bfqq_already_existing) {
bfqq->waker_bfqq = old_bfqq->waker_bfqq; bfqq->waker_bfqq = waker_bfqq;
bfqq->tentative_waker_bfqq = NULL; bfqq->tentative_waker_bfqq = NULL;
/* /*
@ -6809,7 +6838,7 @@ static struct bfq_queue *bfq_init_rq(struct request *rq)
* woken_list of the waker. See * woken_list of the waker. See
* bfq_check_waker for details. * bfq_check_waker for details.
*/ */
if (bfqq->waker_bfqq) if (waker_bfqq)
hlist_add_head(&bfqq->woken_list_node, hlist_add_head(&bfqq->woken_list_node,
&bfqq->waker_bfqq->woken_list); &bfqq->waker_bfqq->woken_list);
} }
@ -6831,7 +6860,8 @@ static struct bfq_queue *bfq_init_rq(struct request *rq)
* addition, if the queue has also just been split, we have to * addition, if the queue has also just been split, we have to
* resume its state. * resume its state.
*/ */
if (likely(bfqq != &bfqd->oom_bfqq) && bfqq_process_refs(bfqq) == 1) { if (likely(bfqq != &bfqd->oom_bfqq) && !bfqq->new_bfqq &&
bfqq_process_refs(bfqq) == 1) {
bfqq->bic = bic; bfqq->bic = bic;
if (split) { if (split) {
/* /*

View File

@ -212,61 +212,44 @@ bool blk_integrity_merge_bio(struct request_queue *q, struct request *req,
return true; return true;
} }
struct integrity_sysfs_entry { static inline struct blk_integrity *dev_to_bi(struct device *dev)
struct attribute attr;
ssize_t (*show)(struct blk_integrity *, char *);
ssize_t (*store)(struct blk_integrity *, const char *, size_t);
};
static ssize_t integrity_attr_show(struct kobject *kobj, struct attribute *attr,
char *page)
{ {
struct gendisk *disk = container_of(kobj, struct gendisk, integrity_kobj); return &dev_to_disk(dev)->queue->integrity;
struct blk_integrity *bi = &disk->queue->integrity;
struct integrity_sysfs_entry *entry =
container_of(attr, struct integrity_sysfs_entry, attr);
return entry->show(bi, page);
} }
static ssize_t integrity_attr_store(struct kobject *kobj, static ssize_t format_show(struct device *dev, struct device_attribute *attr,
struct attribute *attr, const char *page, char *page)
size_t count)
{ {
struct gendisk *disk = container_of(kobj, struct gendisk, integrity_kobj); struct blk_integrity *bi = dev_to_bi(dev);
struct blk_integrity *bi = &disk->queue->integrity;
struct integrity_sysfs_entry *entry =
container_of(attr, struct integrity_sysfs_entry, attr);
ssize_t ret = 0;
if (entry->store)
ret = entry->store(bi, page, count);
return ret;
}
static ssize_t integrity_format_show(struct blk_integrity *bi, char *page)
{
if (bi->profile && bi->profile->name) if (bi->profile && bi->profile->name)
return sprintf(page, "%s\n", bi->profile->name); return sysfs_emit(page, "%s\n", bi->profile->name);
else return sysfs_emit(page, "none\n");
return sprintf(page, "none\n");
} }
static ssize_t integrity_tag_size_show(struct blk_integrity *bi, char *page) static ssize_t tag_size_show(struct device *dev, struct device_attribute *attr,
char *page)
{ {
return sprintf(page, "%u\n", bi->tag_size); struct blk_integrity *bi = dev_to_bi(dev);
return sysfs_emit(page, "%u\n", bi->tag_size);
} }
static ssize_t integrity_interval_show(struct blk_integrity *bi, char *page) static ssize_t protection_interval_bytes_show(struct device *dev,
struct device_attribute *attr,
char *page)
{ {
return sprintf(page, "%u\n", struct blk_integrity *bi = dev_to_bi(dev);
bi->interval_exp ? 1 << bi->interval_exp : 0);
return sysfs_emit(page, "%u\n",
bi->interval_exp ? 1 << bi->interval_exp : 0);
} }
static ssize_t integrity_verify_store(struct blk_integrity *bi, static ssize_t read_verify_store(struct device *dev,
const char *page, size_t count) struct device_attribute *attr,
const char *page, size_t count)
{ {
struct blk_integrity *bi = dev_to_bi(dev);
char *p = (char *) page; char *p = (char *) page;
unsigned long val = simple_strtoul(p, &p, 10); unsigned long val = simple_strtoul(p, &p, 10);
@ -278,14 +261,20 @@ static ssize_t integrity_verify_store(struct blk_integrity *bi,
return count; return count;
} }
static ssize_t integrity_verify_show(struct blk_integrity *bi, char *page) static ssize_t read_verify_show(struct device *dev,
struct device_attribute *attr, char *page)
{ {
return sprintf(page, "%d\n", (bi->flags & BLK_INTEGRITY_VERIFY) != 0); struct blk_integrity *bi = dev_to_bi(dev);
return sysfs_emit(page, "%d\n", !!(bi->flags & BLK_INTEGRITY_VERIFY));
} }
static ssize_t integrity_generate_store(struct blk_integrity *bi, static ssize_t write_generate_store(struct device *dev,
const char *page, size_t count) struct device_attribute *attr,
const char *page, size_t count)
{ {
struct blk_integrity *bi = dev_to_bi(dev);
char *p = (char *) page; char *p = (char *) page;
unsigned long val = simple_strtoul(p, &p, 10); unsigned long val = simple_strtoul(p, &p, 10);
@ -297,68 +286,44 @@ static ssize_t integrity_generate_store(struct blk_integrity *bi,
return count; return count;
} }
static ssize_t integrity_generate_show(struct blk_integrity *bi, char *page) static ssize_t write_generate_show(struct device *dev,
struct device_attribute *attr, char *page)
{ {
return sprintf(page, "%d\n", (bi->flags & BLK_INTEGRITY_GENERATE) != 0); struct blk_integrity *bi = dev_to_bi(dev);
return sysfs_emit(page, "%d\n", !!(bi->flags & BLK_INTEGRITY_GENERATE));
} }
static ssize_t integrity_device_show(struct blk_integrity *bi, char *page) static ssize_t device_is_integrity_capable_show(struct device *dev,
struct device_attribute *attr,
char *page)
{ {
return sprintf(page, "%u\n", struct blk_integrity *bi = dev_to_bi(dev);
(bi->flags & BLK_INTEGRITY_DEVICE_CAPABLE) != 0);
return sysfs_emit(page, "%u\n",
!!(bi->flags & BLK_INTEGRITY_DEVICE_CAPABLE));
} }
static struct integrity_sysfs_entry integrity_format_entry = { static DEVICE_ATTR_RO(format);
.attr = { .name = "format", .mode = 0444 }, static DEVICE_ATTR_RO(tag_size);
.show = integrity_format_show, static DEVICE_ATTR_RO(protection_interval_bytes);
}; static DEVICE_ATTR_RW(read_verify);
static DEVICE_ATTR_RW(write_generate);
static struct integrity_sysfs_entry integrity_tag_size_entry = { static DEVICE_ATTR_RO(device_is_integrity_capable);
.attr = { .name = "tag_size", .mode = 0444 },
.show = integrity_tag_size_show,
};
static struct integrity_sysfs_entry integrity_interval_entry = {
.attr = { .name = "protection_interval_bytes", .mode = 0444 },
.show = integrity_interval_show,
};
static struct integrity_sysfs_entry integrity_verify_entry = {
.attr = { .name = "read_verify", .mode = 0644 },
.show = integrity_verify_show,
.store = integrity_verify_store,
};
static struct integrity_sysfs_entry integrity_generate_entry = {
.attr = { .name = "write_generate", .mode = 0644 },
.show = integrity_generate_show,
.store = integrity_generate_store,
};
static struct integrity_sysfs_entry integrity_device_entry = {
.attr = { .name = "device_is_integrity_capable", .mode = 0444 },
.show = integrity_device_show,
};
static struct attribute *integrity_attrs[] = { static struct attribute *integrity_attrs[] = {
&integrity_format_entry.attr, &dev_attr_format.attr,
&integrity_tag_size_entry.attr, &dev_attr_tag_size.attr,
&integrity_interval_entry.attr, &dev_attr_protection_interval_bytes.attr,
&integrity_verify_entry.attr, &dev_attr_read_verify.attr,
&integrity_generate_entry.attr, &dev_attr_write_generate.attr,
&integrity_device_entry.attr, &dev_attr_device_is_integrity_capable.attr,
NULL, NULL
};
ATTRIBUTE_GROUPS(integrity);
static const struct sysfs_ops integrity_ops = {
.show = &integrity_attr_show,
.store = &integrity_attr_store,
}; };
static struct kobj_type integrity_ktype = { const struct attribute_group blk_integrity_attr_group = {
.default_groups = integrity_groups, .name = "integrity",
.sysfs_ops = &integrity_ops, .attrs = integrity_attrs,
}; };
static blk_status_t blk_integrity_nop_fn(struct blk_integrity_iter *iter) static blk_status_t blk_integrity_nop_fn(struct blk_integrity_iter *iter)
@ -435,21 +400,3 @@ void blk_integrity_unregister(struct gendisk *disk)
memset(bi, 0, sizeof(*bi)); memset(bi, 0, sizeof(*bi));
} }
EXPORT_SYMBOL(blk_integrity_unregister); EXPORT_SYMBOL(blk_integrity_unregister);
int blk_integrity_add(struct gendisk *disk)
{
int ret;
ret = kobject_init_and_add(&disk->integrity_kobj, &integrity_ktype,
&disk_to_dev(disk)->kobj, "%s", "integrity");
if (!ret)
kobject_uevent(&disk->integrity_kobj, KOBJ_ADD);
return ret;
}
void blk_integrity_del(struct gendisk *disk)
{
kobject_uevent(&disk->integrity_kobj, KOBJ_REMOVE);
kobject_del(&disk->integrity_kobj);
kobject_put(&disk->integrity_kobj);
}

View File

@ -2057,7 +2057,7 @@ static void ioc_forgive_debts(struct ioc *ioc, u64 usage_us_sum, int nr_debtors,
struct ioc_now *now) struct ioc_now *now)
{ {
struct ioc_gq *iocg; struct ioc_gq *iocg;
u64 dur, usage_pct, nr_cycles; u64 dur, usage_pct, nr_cycles, nr_cycles_shift;
/* if no debtor, reset the cycle */ /* if no debtor, reset the cycle */
if (!nr_debtors) { if (!nr_debtors) {
@ -2119,10 +2119,12 @@ static void ioc_forgive_debts(struct ioc *ioc, u64 usage_us_sum, int nr_debtors,
old_debt = iocg->abs_vdebt; old_debt = iocg->abs_vdebt;
old_delay = iocg->delay; old_delay = iocg->delay;
nr_cycles_shift = min_t(u64, nr_cycles, BITS_PER_LONG - 1);
if (iocg->abs_vdebt) if (iocg->abs_vdebt)
iocg->abs_vdebt = iocg->abs_vdebt >> nr_cycles ?: 1; iocg->abs_vdebt = iocg->abs_vdebt >> nr_cycles_shift ?: 1;
if (iocg->delay) if (iocg->delay)
iocg->delay = iocg->delay >> nr_cycles ?: 1; iocg->delay = iocg->delay >> nr_cycles_shift ?: 1;
iocg_kick_waitq(iocg, true, now); iocg_kick_waitq(iocg, true, now);

View File

@ -212,8 +212,7 @@ static inline bool integrity_req_gap_front_merge(struct request *req,
bip_next->bip_vec[0].bv_offset); bip_next->bip_vec[0].bv_offset);
} }
int blk_integrity_add(struct gendisk *disk); extern const struct attribute_group blk_integrity_attr_group;
void blk_integrity_del(struct gendisk *);
#else /* CONFIG_BLK_DEV_INTEGRITY */ #else /* CONFIG_BLK_DEV_INTEGRITY */
static inline bool blk_integrity_merge_rq(struct request_queue *rq, static inline bool blk_integrity_merge_rq(struct request_queue *rq,
struct request *r1, struct request *r2) struct request *r1, struct request *r2)
@ -246,13 +245,6 @@ static inline bool bio_integrity_endio(struct bio *bio)
static inline void bio_integrity_free(struct bio *bio) static inline void bio_integrity_free(struct bio *bio)
{ {
} }
static inline int blk_integrity_add(struct gendisk *disk)
{
return 0;
}
static inline void blk_integrity_del(struct gendisk *disk)
{
}
#endif /* CONFIG_BLK_DEV_INTEGRITY */ #endif /* CONFIG_BLK_DEV_INTEGRITY */
unsigned long blk_rq_timeout(unsigned long timeout); unsigned long blk_rq_timeout(unsigned long timeout);

View File

@ -489,15 +489,11 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk,
*/ */
pm_runtime_set_memalloc_noio(ddev, true); pm_runtime_set_memalloc_noio(ddev, true);
ret = blk_integrity_add(disk);
if (ret)
goto out_del_block_link;
disk->part0->bd_holder_dir = disk->part0->bd_holder_dir =
kobject_create_and_add("holders", &ddev->kobj); kobject_create_and_add("holders", &ddev->kobj);
if (!disk->part0->bd_holder_dir) { if (!disk->part0->bd_holder_dir) {
ret = -ENOMEM; ret = -ENOMEM;
goto out_del_integrity; goto out_del_block_link;
} }
disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj); disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj);
if (!disk->slave_dir) { if (!disk->slave_dir) {
@ -564,8 +560,6 @@ out_put_slave_dir:
disk->slave_dir = NULL; disk->slave_dir = NULL;
out_put_holder_dir: out_put_holder_dir:
kobject_put(disk->part0->bd_holder_dir); kobject_put(disk->part0->bd_holder_dir);
out_del_integrity:
blk_integrity_del(disk);
out_del_block_link: out_del_block_link:
if (!sysfs_deprecated) if (!sysfs_deprecated)
sysfs_remove_link(block_depr, dev_name(ddev)); sysfs_remove_link(block_depr, dev_name(ddev));
@ -624,7 +618,6 @@ void del_gendisk(struct gendisk *disk)
if (WARN_ON_ONCE(!disk_live(disk) && !(disk->flags & GENHD_FL_HIDDEN))) if (WARN_ON_ONCE(!disk_live(disk) && !(disk->flags & GENHD_FL_HIDDEN)))
return; return;
blk_integrity_del(disk);
disk_del_events(disk); disk_del_events(disk);
mutex_lock(&disk->open_mutex); mutex_lock(&disk->open_mutex);
@ -1160,6 +1153,9 @@ static const struct attribute_group *disk_attr_groups[] = {
&disk_attr_group, &disk_attr_group,
#ifdef CONFIG_BLK_DEV_IO_TRACE #ifdef CONFIG_BLK_DEV_IO_TRACE
&blk_trace_attr_group, &blk_trace_attr_group,
#endif
#ifdef CONFIG_BLK_DEV_INTEGRITY
&blk_integrity_attr_group,
#endif #endif
NULL NULL
}; };

View File

@ -580,9 +580,11 @@ static bool blk_add_partition(struct gendisk *disk,
part = add_partition(disk, p, from, size, state->parts[p].flags, part = add_partition(disk, p, from, size, state->parts[p].flags,
&state->parts[p].info); &state->parts[p].info);
if (IS_ERR(part) && PTR_ERR(part) != -ENXIO) { if (IS_ERR(part)) {
printk(KERN_ERR " %s: p%d could not be added: %ld\n", if (PTR_ERR(part) != -ENXIO) {
disk->disk_name, p, -PTR_ERR(part)); printk(KERN_ERR " %s: p%d could not be added: %pe\n",
disk->disk_name, p, part);
}
return true; return true;
} }

View File

@ -61,17 +61,18 @@ struct key *find_asymmetric_key(struct key *keyring,
char *req, *p; char *req, *p;
int len; int len;
WARN_ON(!id_0 && !id_1 && !id_2);
if (id_0) { if (id_0) {
lookup = id_0->data; lookup = id_0->data;
len = id_0->len; len = id_0->len;
} else if (id_1) { } else if (id_1) {
lookup = id_1->data; lookup = id_1->data;
len = id_1->len; len = id_1->len;
} else { } else if (id_2) {
lookup = id_2->data; lookup = id_2->data;
len = id_2->len; len = id_2->len;
} else {
WARN_ON(1);
return ERR_PTR(-EINVAL);
} }
/* Construct an identifier "id:<keyid>". */ /* Construct an identifier "id:<keyid>". */

View File

@ -136,27 +136,19 @@ static int simd_skcipher_init(struct crypto_skcipher *tfm)
return 0; return 0;
} }
struct simd_skcipher_alg *simd_skcipher_create_compat(const char *algname, struct simd_skcipher_alg *simd_skcipher_create_compat(struct skcipher_alg *ialg,
const char *algname,
const char *drvname, const char *drvname,
const char *basename) const char *basename)
{ {
struct simd_skcipher_alg *salg; struct simd_skcipher_alg *salg;
struct crypto_skcipher *tfm;
struct skcipher_alg *ialg;
struct skcipher_alg *alg; struct skcipher_alg *alg;
int err; int err;
tfm = crypto_alloc_skcipher(basename, CRYPTO_ALG_INTERNAL,
CRYPTO_ALG_INTERNAL | CRYPTO_ALG_ASYNC);
if (IS_ERR(tfm))
return ERR_CAST(tfm);
ialg = crypto_skcipher_alg(tfm);
salg = kzalloc(sizeof(*salg), GFP_KERNEL); salg = kzalloc(sizeof(*salg), GFP_KERNEL);
if (!salg) { if (!salg) {
salg = ERR_PTR(-ENOMEM); salg = ERR_PTR(-ENOMEM);
goto out_put_tfm; goto out;
} }
salg->ialg_name = basename; salg->ialg_name = basename;
@ -195,30 +187,16 @@ struct simd_skcipher_alg *simd_skcipher_create_compat(const char *algname,
if (err) if (err)
goto out_free_salg; goto out_free_salg;
out_put_tfm: out:
crypto_free_skcipher(tfm);
return salg; return salg;
out_free_salg: out_free_salg:
kfree(salg); kfree(salg);
salg = ERR_PTR(err); salg = ERR_PTR(err);
goto out_put_tfm; goto out;
} }
EXPORT_SYMBOL_GPL(simd_skcipher_create_compat); EXPORT_SYMBOL_GPL(simd_skcipher_create_compat);
struct simd_skcipher_alg *simd_skcipher_create(const char *algname,
const char *basename)
{
char drvname[CRYPTO_MAX_ALG_NAME];
if (snprintf(drvname, CRYPTO_MAX_ALG_NAME, "simd-%s", basename) >=
CRYPTO_MAX_ALG_NAME)
return ERR_PTR(-ENAMETOOLONG);
return simd_skcipher_create_compat(algname, drvname, basename);
}
EXPORT_SYMBOL_GPL(simd_skcipher_create);
void simd_skcipher_free(struct simd_skcipher_alg *salg) void simd_skcipher_free(struct simd_skcipher_alg *salg)
{ {
crypto_unregister_skcipher(&salg->alg); crypto_unregister_skcipher(&salg->alg);
@ -246,7 +224,7 @@ int simd_register_skciphers_compat(struct skcipher_alg *algs, int count,
algname = algs[i].base.cra_name + 2; algname = algs[i].base.cra_name + 2;
drvname = algs[i].base.cra_driver_name + 2; drvname = algs[i].base.cra_driver_name + 2;
basename = algs[i].base.cra_driver_name; basename = algs[i].base.cra_driver_name;
simd = simd_skcipher_create_compat(algname, drvname, basename); simd = simd_skcipher_create_compat(algs + i, algname, drvname, basename);
err = PTR_ERR(simd); err = PTR_ERR(simd);
if (IS_ERR(simd)) if (IS_ERR(simd))
goto err_unregister; goto err_unregister;
@ -383,27 +361,19 @@ static int simd_aead_init(struct crypto_aead *tfm)
return 0; return 0;
} }
struct simd_aead_alg *simd_aead_create_compat(const char *algname, static struct simd_aead_alg *simd_aead_create_compat(struct aead_alg *ialg,
const char *drvname, const char *algname,
const char *basename) const char *drvname,
const char *basename)
{ {
struct simd_aead_alg *salg; struct simd_aead_alg *salg;
struct crypto_aead *tfm;
struct aead_alg *ialg;
struct aead_alg *alg; struct aead_alg *alg;
int err; int err;
tfm = crypto_alloc_aead(basename, CRYPTO_ALG_INTERNAL,
CRYPTO_ALG_INTERNAL | CRYPTO_ALG_ASYNC);
if (IS_ERR(tfm))
return ERR_CAST(tfm);
ialg = crypto_aead_alg(tfm);
salg = kzalloc(sizeof(*salg), GFP_KERNEL); salg = kzalloc(sizeof(*salg), GFP_KERNEL);
if (!salg) { if (!salg) {
salg = ERR_PTR(-ENOMEM); salg = ERR_PTR(-ENOMEM);
goto out_put_tfm; goto out;
} }
salg->ialg_name = basename; salg->ialg_name = basename;
@ -442,36 +412,20 @@ struct simd_aead_alg *simd_aead_create_compat(const char *algname,
if (err) if (err)
goto out_free_salg; goto out_free_salg;
out_put_tfm: out:
crypto_free_aead(tfm);
return salg; return salg;
out_free_salg: out_free_salg:
kfree(salg); kfree(salg);
salg = ERR_PTR(err); salg = ERR_PTR(err);
goto out_put_tfm; goto out;
} }
EXPORT_SYMBOL_GPL(simd_aead_create_compat);
struct simd_aead_alg *simd_aead_create(const char *algname, static void simd_aead_free(struct simd_aead_alg *salg)
const char *basename)
{
char drvname[CRYPTO_MAX_ALG_NAME];
if (snprintf(drvname, CRYPTO_MAX_ALG_NAME, "simd-%s", basename) >=
CRYPTO_MAX_ALG_NAME)
return ERR_PTR(-ENAMETOOLONG);
return simd_aead_create_compat(algname, drvname, basename);
}
EXPORT_SYMBOL_GPL(simd_aead_create);
void simd_aead_free(struct simd_aead_alg *salg)
{ {
crypto_unregister_aead(&salg->alg); crypto_unregister_aead(&salg->alg);
kfree(salg); kfree(salg);
} }
EXPORT_SYMBOL_GPL(simd_aead_free);
int simd_register_aeads_compat(struct aead_alg *algs, int count, int simd_register_aeads_compat(struct aead_alg *algs, int count,
struct simd_aead_alg **simd_algs) struct simd_aead_alg **simd_algs)
@ -493,7 +447,7 @@ int simd_register_aeads_compat(struct aead_alg *algs, int count,
algname = algs[i].base.cra_name + 2; algname = algs[i].base.cra_name + 2;
drvname = algs[i].base.cra_driver_name + 2; drvname = algs[i].base.cra_driver_name + 2;
basename = algs[i].base.cra_driver_name; basename = algs[i].base.cra_driver_name;
simd = simd_aead_create_compat(algname, drvname, basename); simd = simd_aead_create_compat(algs + i, algname, drvname, basename);
err = PTR_ERR(simd); err = PTR_ERR(simd);
if (IS_ERR(simd)) if (IS_ERR(simd))
goto err_unregister; goto err_unregister;

View File

@ -83,33 +83,30 @@ static void __init
do_xor_speed(struct xor_block_template *tmpl, void *b1, void *b2) do_xor_speed(struct xor_block_template *tmpl, void *b1, void *b2)
{ {
int speed; int speed;
int i, j; unsigned long reps;
ktime_t min, start, diff; ktime_t min, start, t0;
tmpl->next = template_list; tmpl->next = template_list;
template_list = tmpl; template_list = tmpl;
preempt_disable(); preempt_disable();
min = (ktime_t)S64_MAX; reps = 0;
for (i = 0; i < 3; i++) { t0 = ktime_get();
start = ktime_get(); /* delay start until time has advanced */
for (j = 0; j < REPS; j++) { while ((start = ktime_get()) == t0)
mb(); /* prevent loop optimization */ cpu_relax();
tmpl->do_2(BENCH_SIZE, b1, b2); do {
mb(); mb(); /* prevent loop optimization */
} tmpl->do_2(BENCH_SIZE, b1, b2);
diff = ktime_sub(ktime_get(), start); mb();
if (diff < min) } while (reps++ < REPS || (t0 = ktime_get()) == start);
min = diff; min = ktime_sub(t0, start);
}
preempt_enable(); preempt_enable();
// bytes/ns == GB/s, multiply by 1000 to get MB/s [not MiB/s] // bytes/ns == GB/s, multiply by 1000 to get MB/s [not MiB/s]
if (!min) speed = (1000 * reps * BENCH_SIZE) / (unsigned int)ktime_to_ns(min);
min = 1;
speed = (1000 * REPS * BENCH_SIZE) / (unsigned int)ktime_to_ns(min);
tmpl->speed = speed; tmpl->speed = speed;
pr_info(" %-16s: %5d MB/sec\n", tmpl->name, speed); pr_info(" %-16s: %5d MB/sec\n", tmpl->name, speed);

View File

@ -130,8 +130,10 @@ static void exit_round_robin(unsigned int tsk_index)
{ {
struct cpumask *pad_busy_cpus = to_cpumask(pad_busy_cpus_bits); struct cpumask *pad_busy_cpus = to_cpumask(pad_busy_cpus_bits);
cpumask_clear_cpu(tsk_in_cpu[tsk_index], pad_busy_cpus); if (tsk_in_cpu[tsk_index] != -1) {
tsk_in_cpu[tsk_index] = -1; cpumask_clear_cpu(tsk_in_cpu[tsk_index], pad_busy_cpus);
tsk_in_cpu[tsk_index] = -1;
}
} }
static unsigned int idle_pct = 5; /* percentage */ static unsigned int idle_pct = 5; /* percentage */

View File

@ -174,6 +174,8 @@ acpi_status acpi_db_convert_to_package(char *string, union acpi_object *object)
elements = elements =
ACPI_ALLOCATE_ZEROED(DB_DEFAULT_PKG_ELEMENTS * ACPI_ALLOCATE_ZEROED(DB_DEFAULT_PKG_ELEMENTS *
sizeof(union acpi_object)); sizeof(union acpi_object));
if (!elements)
return (AE_NO_MEMORY);
this = string; this = string;
for (i = 0; i < (DB_DEFAULT_PKG_ELEMENTS - 1); i++) { for (i = 0; i < (DB_DEFAULT_PKG_ELEMENTS - 1); i++) {

View File

@ -437,6 +437,9 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
if (info->connection_node) { if (info->connection_node) {
second_desc = info->connection_node->object; second_desc = info->connection_node->object;
if (second_desc == NULL) {
break;
}
if (!(second_desc->common.flags & AOPOBJ_DATA_VALID)) { if (!(second_desc->common.flags & AOPOBJ_DATA_VALID)) {
status = status =
acpi_ds_get_buffer_arguments(second_desc); acpi_ds_get_buffer_arguments(second_desc);

View File

@ -133,14 +133,15 @@ acpi_status acpi_ex_system_do_stall(u32 how_long_us)
* (ACPI specifies 100 usec as max, but this gives some slack in * (ACPI specifies 100 usec as max, but this gives some slack in
* order to support existing BIOSs) * order to support existing BIOSs)
*/ */
ACPI_ERROR((AE_INFO, ACPI_ERROR_ONCE((AE_INFO,
"Time parameter is too large (%u)", how_long_us)); "Time parameter is too large (%u)",
how_long_us));
status = AE_AML_OPERAND_VALUE; status = AE_AML_OPERAND_VALUE;
} else { } else {
if (how_long_us > 100) { if (how_long_us > 100) {
ACPI_WARNING((AE_INFO, ACPI_WARNING_ONCE((AE_INFO,
"Time parameter %u us > 100 us violating ACPI spec, please fix the firmware.", "Time parameter %u us > 100 us violating ACPI spec, please fix the firmware.",
how_long_us)); how_long_us));
} }
acpi_os_stall(how_long_us); acpi_os_stall(how_long_us);
} }

View File

@ -25,6 +25,8 @@ acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state);
static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
*parser_state); *parser_state);
static void acpi_ps_free_field_list(union acpi_parse_object *start);
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_ps_get_next_package_length * FUNCTION: acpi_ps_get_next_package_length
@ -683,6 +685,39 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
return_PTR(field); return_PTR(field);
} }
/*******************************************************************************
*
* FUNCTION: acpi_ps_free_field_list
*
* PARAMETERS: start - First Op in field list
*
* RETURN: None.
*
* DESCRIPTION: Free all Op objects inside a field list.
*
******************************************************************************/
static void acpi_ps_free_field_list(union acpi_parse_object *start)
{
union acpi_parse_object *cur = start;
union acpi_parse_object *next;
union acpi_parse_object *arg;
while (cur) {
next = cur->common.next;
/* AML_INT_CONNECTION_OP can have a single argument */
arg = acpi_ps_get_arg(cur, 0);
if (arg) {
acpi_ps_free_op(arg);
}
acpi_ps_free_op(cur);
cur = next;
}
}
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_ps_get_next_arg * FUNCTION: acpi_ps_get_next_arg
@ -751,6 +786,10 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
while (parser_state->aml < parser_state->pkg_end) { while (parser_state->aml < parser_state->pkg_end) {
field = acpi_ps_get_next_field(parser_state); field = acpi_ps_get_next_field(parser_state);
if (!field) { if (!field) {
if (arg) {
acpi_ps_free_field_list(arg);
}
return_ACPI_STATUS(AE_NO_MEMORY); return_ACPI_STATUS(AE_NO_MEMORY);
} }
@ -820,6 +859,10 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
acpi_ps_get_next_namepath(walk_state, parser_state, acpi_ps_get_next_namepath(walk_state, parser_state,
arg, arg,
ACPI_NOT_METHOD_CALL); ACPI_NOT_METHOD_CALL);
if (ACPI_FAILURE(status)) {
acpi_ps_free_op(arg);
return_ACPI_STATUS(status);
}
} else { } else {
/* Single complex argument, nothing returned */ /* Single complex argument, nothing returned */
@ -854,6 +897,10 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
acpi_ps_get_next_namepath(walk_state, parser_state, acpi_ps_get_next_namepath(walk_state, parser_state,
arg, arg,
ACPI_POSSIBLE_METHOD_CALL); ACPI_POSSIBLE_METHOD_CALL);
if (ACPI_FAILURE(status)) {
acpi_ps_free_op(arg);
return_ACPI_STATUS(status);
}
if (arg->common.aml_opcode == AML_INT_METHODCALL_OP) { if (arg->common.aml_opcode == AML_INT_METHODCALL_OP) {

View File

@ -692,27 +692,34 @@ static LIST_HEAD(acpi_battery_list);
static LIST_HEAD(battery_hook_list); static LIST_HEAD(battery_hook_list);
static DEFINE_MUTEX(hook_mutex); static DEFINE_MUTEX(hook_mutex);
static void __battery_hook_unregister(struct acpi_battery_hook *hook, int lock) static void battery_hook_unregister_unlocked(struct acpi_battery_hook *hook)
{ {
struct acpi_battery *battery; struct acpi_battery *battery;
/* /*
* In order to remove a hook, we first need to * In order to remove a hook, we first need to
* de-register all the batteries that are registered. * de-register all the batteries that are registered.
*/ */
if (lock)
mutex_lock(&hook_mutex);
list_for_each_entry(battery, &acpi_battery_list, list) { list_for_each_entry(battery, &acpi_battery_list, list) {
hook->remove_battery(battery->bat); hook->remove_battery(battery->bat);
} }
list_del(&hook->list); list_del_init(&hook->list);
if (lock)
mutex_unlock(&hook_mutex);
pr_info("extension unregistered: %s\n", hook->name); pr_info("extension unregistered: %s\n", hook->name);
} }
void battery_hook_unregister(struct acpi_battery_hook *hook) void battery_hook_unregister(struct acpi_battery_hook *hook)
{ {
__battery_hook_unregister(hook, 1); mutex_lock(&hook_mutex);
/*
* Ignore already unregistered battery hooks. This might happen
* if a battery hook was previously unloaded due to an error when
* adding a new battery.
*/
if (!list_empty(&hook->list))
battery_hook_unregister_unlocked(hook);
mutex_unlock(&hook_mutex);
} }
EXPORT_SYMBOL_GPL(battery_hook_unregister); EXPORT_SYMBOL_GPL(battery_hook_unregister);
@ -721,7 +728,6 @@ void battery_hook_register(struct acpi_battery_hook *hook)
struct acpi_battery *battery; struct acpi_battery *battery;
mutex_lock(&hook_mutex); mutex_lock(&hook_mutex);
INIT_LIST_HEAD(&hook->list);
list_add(&hook->list, &battery_hook_list); list_add(&hook->list, &battery_hook_list);
/* /*
* Now that the driver is registered, we need * Now that the driver is registered, we need
@ -738,7 +744,7 @@ void battery_hook_register(struct acpi_battery_hook *hook)
* hooks. * hooks.
*/ */
pr_err("extension failed to load: %s", hook->name); pr_err("extension failed to load: %s", hook->name);
__battery_hook_unregister(hook, 0); battery_hook_unregister_unlocked(hook);
goto end; goto end;
} }
} }
@ -775,7 +781,7 @@ static void battery_hook_add_battery(struct acpi_battery *battery)
*/ */
pr_err("error in extension, unloading: %s", pr_err("error in extension, unloading: %s",
hook_node->name); hook_node->name);
__battery_hook_unregister(hook_node, 0); battery_hook_unregister_unlocked(hook_node);
} }
} }
mutex_unlock(&hook_mutex); mutex_unlock(&hook_mutex);
@ -808,7 +814,7 @@ static void __exit battery_hook_exit(void)
* need to remove the hooks. * need to remove the hooks.
*/ */
list_for_each_entry_safe(hook, ptr, &battery_hook_list, list) { list_for_each_entry_safe(hook, ptr, &battery_hook_list, list) {
__battery_hook_unregister(hook, 1); battery_hook_unregister(hook);
} }
mutex_destroy(&hook_mutex); mutex_destroy(&hook_mutex);
} }

View File

@ -167,8 +167,11 @@ show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, wraparound_time);
#define GET_BIT_WIDTH(reg) ((reg)->access_width ? (8 << ((reg)->access_width - 1)) : (reg)->bit_width) #define GET_BIT_WIDTH(reg) ((reg)->access_width ? (8 << ((reg)->access_width - 1)) : (reg)->bit_width)
/* Shift and apply the mask for CPC reads/writes */ /* Shift and apply the mask for CPC reads/writes */
#define MASK_VAL(reg, val) (((val) >> (reg)->bit_offset) & \ #define MASK_VAL_READ(reg, val) (((val) >> (reg)->bit_offset) & \
GENMASK(((reg)->bit_width) - 1, 0)) GENMASK(((reg)->bit_width) - 1, 0))
#define MASK_VAL_WRITE(reg, prev_val, val) \
((((val) & GENMASK(((reg)->bit_width) - 1, 0)) << (reg)->bit_offset) | \
((prev_val) & ~(GENMASK(((reg)->bit_width) - 1, 0) << (reg)->bit_offset))) \
static ssize_t show_feedback_ctrs(struct kobject *kobj, static ssize_t show_feedback_ctrs(struct kobject *kobj,
struct kobj_attribute *attr, char *buf) struct kobj_attribute *attr, char *buf)
@ -851,6 +854,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
/* Store CPU Logical ID */ /* Store CPU Logical ID */
cpc_ptr->cpu_id = pr->id; cpc_ptr->cpu_id = pr->id;
spin_lock_init(&cpc_ptr->rmw_lock);
/* Parse PSD data for this CPU */ /* Parse PSD data for this CPU */
ret = acpi_get_psd(cpc_ptr, handle); ret = acpi_get_psd(cpc_ptr, handle);
@ -1056,7 +1060,7 @@ static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val)
} }
if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
*val = MASK_VAL(reg, *val); *val = MASK_VAL_READ(reg, *val);
return 0; return 0;
} }
@ -1065,9 +1069,11 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
{ {
int ret_val = 0; int ret_val = 0;
int size; int size;
u64 prev_val;
void __iomem *vaddr = NULL; void __iomem *vaddr = NULL;
int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu);
struct cpc_reg *reg = &reg_res->cpc_entry.reg; struct cpc_reg *reg = &reg_res->cpc_entry.reg;
struct cpc_desc *cpc_desc;
size = GET_BIT_WIDTH(reg); size = GET_BIT_WIDTH(reg);
@ -1100,8 +1106,34 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
return acpi_os_write_memory((acpi_physical_address)reg->address, return acpi_os_write_memory((acpi_physical_address)reg->address,
val, size); val, size);
if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
val = MASK_VAL(reg, val); cpc_desc = per_cpu(cpc_desc_ptr, cpu);
if (!cpc_desc) {
pr_debug("No CPC descriptor for CPU:%d\n", cpu);
return -ENODEV;
}
spin_lock(&cpc_desc->rmw_lock);
switch (size) {
case 8:
prev_val = readb_relaxed(vaddr);
break;
case 16:
prev_val = readw_relaxed(vaddr);
break;
case 32:
prev_val = readl_relaxed(vaddr);
break;
case 64:
prev_val = readq_relaxed(vaddr);
break;
default:
spin_unlock(&cpc_desc->rmw_lock);
return -EFAULT;
}
val = MASK_VAL_WRITE(reg, prev_val, val);
val |= prev_val;
}
switch (size) { switch (size) {
case 8: case 8:
@ -1128,6 +1160,9 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
break; break;
} }
if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
spin_unlock(&cpc_desc->rmw_lock);
return ret_val; return ret_val;
} }

View File

@ -544,8 +544,9 @@ int acpi_device_setup_files(struct acpi_device *dev)
* If device has _STR, 'description' file is created * If device has _STR, 'description' file is created
*/ */
if (acpi_has_method(dev->handle, "_STR")) { if (acpi_has_method(dev->handle, "_STR")) {
status = acpi_evaluate_object(dev->handle, "_STR", status = acpi_evaluate_object_typed(dev->handle, "_STR",
NULL, &buffer); NULL, &buffer,
ACPI_TYPE_BUFFER);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
buffer.pointer = NULL; buffer.pointer = NULL;
dev->pnp.str_obj = buffer.pointer; dev->pnp.str_obj = buffer.pointer;

View File

@ -797,6 +797,9 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
unsigned long tmp; unsigned long tmp;
int ret = 0; int ret = 0;
if (t->rdata)
memset(t->rdata, 0, t->rlen);
/* start transaction */ /* start transaction */
spin_lock_irqsave(&ec->lock, tmp); spin_lock_irqsave(&ec->lock, tmp);
/* Enable GPE for command processing (IBF=0/OBF=1) */ /* Enable GPE for command processing (IBF=0/OBF=1) */
@ -833,8 +836,6 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
if (!ec || (!t) || (t->wlen && !t->wdata) || (t->rlen && !t->rdata)) if (!ec || (!t) || (t->wlen && !t->wdata) || (t->rlen && !t->rdata))
return -EINVAL; return -EINVAL;
if (t->rdata)
memset(t->rdata, 0, t->rlen);
mutex_lock(&ec->mutex); mutex_lock(&ec->mutex);
if (ec->global_lock) { if (ec->global_lock) {
@ -861,7 +862,7 @@ static int acpi_ec_burst_enable(struct acpi_ec *ec)
.wdata = NULL, .rdata = &d, .wdata = NULL, .rdata = &d,
.wlen = 0, .rlen = 1}; .wlen = 0, .rlen = 1};
return acpi_ec_transaction(ec, &t); return acpi_ec_transaction_unlocked(ec, &t);
} }
static int acpi_ec_burst_disable(struct acpi_ec *ec) static int acpi_ec_burst_disable(struct acpi_ec *ec)
@ -871,7 +872,7 @@ static int acpi_ec_burst_disable(struct acpi_ec *ec)
.wlen = 0, .rlen = 0}; .wlen = 0, .rlen = 0};
return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ? return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ?
acpi_ec_transaction(ec, &t) : 0; acpi_ec_transaction_unlocked(ec, &t) : 0;
} }
static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data) static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data)
@ -887,6 +888,19 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data)
return result; return result;
} }
static int acpi_ec_read_unlocked(struct acpi_ec *ec, u8 address, u8 *data)
{
int result;
u8 d;
struct transaction t = {.command = ACPI_EC_COMMAND_READ,
.wdata = &address, .rdata = &d,
.wlen = 1, .rlen = 1};
result = acpi_ec_transaction_unlocked(ec, &t);
*data = d;
return result;
}
static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
{ {
u8 wdata[2] = { address, data }; u8 wdata[2] = { address, data };
@ -897,6 +911,16 @@ static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
return acpi_ec_transaction(ec, &t); return acpi_ec_transaction(ec, &t);
} }
static int acpi_ec_write_unlocked(struct acpi_ec *ec, u8 address, u8 data)
{
u8 wdata[2] = { address, data };
struct transaction t = {.command = ACPI_EC_COMMAND_WRITE,
.wdata = wdata, .rdata = NULL,
.wlen = 2, .rlen = 0};
return acpi_ec_transaction_unlocked(ec, &t);
}
int ec_read(u8 addr, u8 *val) int ec_read(u8 addr, u8 *val)
{ {
int err; int err;
@ -1304,6 +1328,7 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
struct acpi_ec *ec = handler_context; struct acpi_ec *ec = handler_context;
int result = 0, i, bytes = bits / 8; int result = 0, i, bytes = bits / 8;
u8 *value = (u8 *)value64; u8 *value = (u8 *)value64;
u32 glk;
if ((address > 0xFF) || !value || !handler_context) if ((address > 0xFF) || !value || !handler_context)
return AE_BAD_PARAMETER; return AE_BAD_PARAMETER;
@ -1311,13 +1336,25 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
if (function != ACPI_READ && function != ACPI_WRITE) if (function != ACPI_READ && function != ACPI_WRITE)
return AE_BAD_PARAMETER; return AE_BAD_PARAMETER;
mutex_lock(&ec->mutex);
if (ec->global_lock) {
acpi_status status;
status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
if (ACPI_FAILURE(status)) {
result = -ENODEV;
goto unlock;
}
}
if (ec->busy_polling || bits > 8) if (ec->busy_polling || bits > 8)
acpi_ec_burst_enable(ec); acpi_ec_burst_enable(ec);
for (i = 0; i < bytes; ++i, ++address, ++value) { for (i = 0; i < bytes; ++i, ++address, ++value) {
result = (function == ACPI_READ) ? result = (function == ACPI_READ) ?
acpi_ec_read(ec, address, value) : acpi_ec_read_unlocked(ec, address, value) :
acpi_ec_write(ec, address, *value); acpi_ec_write_unlocked(ec, address, *value);
if (result < 0) if (result < 0)
break; break;
} }
@ -1325,6 +1362,12 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
if (ec->busy_polling || bits > 8) if (ec->busy_polling || bits > 8)
acpi_ec_burst_disable(ec); acpi_ec_burst_disable(ec);
if (ec->global_lock)
acpi_release_global_lock(glk);
unlock:
mutex_unlock(&ec->mutex);
switch (result) { switch (result) {
case -EINVAL: case -EINVAL:
return AE_BAD_PARAMETER; return AE_BAD_PARAMETER;

View File

@ -376,10 +376,8 @@ static int tps68470_pmic_opregion_probe(struct platform_device *pdev)
struct tps68470_pmic_opregion *opregion; struct tps68470_pmic_opregion *opregion;
acpi_status status; acpi_status status;
if (!dev || !tps68470_regmap) { if (!tps68470_regmap)
dev_warn(dev, "dev or regmap is NULL\n"); return dev_err_probe(dev, -EINVAL, "regmap is missing\n");
return -EINVAL;
}
if (!handle) { if (!handle) {
dev_warn(dev, "acpi handle is NULL\n"); dev_warn(dev, "acpi handle is NULL\n");

View File

@ -439,6 +439,13 @@ static const struct dmi_system_id asus_laptop[] = {
DMI_MATCH(DMI_BOARD_NAME, "S5602ZA"), DMI_MATCH(DMI_BOARD_NAME, "S5602ZA"),
}, },
}, },
{
/* Asus Vivobook X1704VAP */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_BOARD_NAME, "X1704VAP"),
},
},
{ {
.ident = "Asus ExpertBook B1402CBA", .ident = "Asus ExpertBook B1402CBA",
.matches = { .matches = {
@ -506,12 +513,25 @@ static const struct dmi_system_id maingear_laptop[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "MG-VCP2-15A3070T"), DMI_MATCH(DMI_PRODUCT_NAME, "MG-VCP2-15A3070T"),
} }
}, },
{
/* Asus ExpertBook B2502CVA */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_BOARD_NAME, "B2502CVA"),
},
},
{ {
/* TongFang GMxXGxx/TUXEDO Polaris 15 Gen5 AMD */ /* TongFang GMxXGxx/TUXEDO Polaris 15 Gen5 AMD */
.matches = { .matches = {
DMI_MATCH(DMI_BOARD_NAME, "GMxXGxx"), DMI_MATCH(DMI_BOARD_NAME, "GMxXGxx"),
}, },
}, },
{
/* TongFang GMxXGxX/TUXEDO Polaris 15 Gen5 AMD */
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "GMxXGxX"),
},
},
{ {
/* TongFang GMxXGxx sold as Eluktronics Inc. RP-15 */ /* TongFang GMxXGxx sold as Eluktronics Inc. RP-15 */
.matches = { .matches = {

View File

@ -258,6 +258,14 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "PCG-FRV35"), DMI_MATCH(DMI_PRODUCT_NAME, "PCG-FRV35"),
}, },
}, },
{
.callback = video_detect_force_vendor,
/* Panasonic Toughbook CF-18 */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Matsushita Electric Industrial"),
DMI_MATCH(DMI_PRODUCT_NAME, "CF-18"),
},
},
/* /*
* Toshiba models with Transflective display, these need to use * Toshiba models with Transflective display, these need to use

View File

@ -3946,10 +3946,20 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap)
WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED); WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED);
/* Set all devices attached to the port in standby mode */ /*
ata_for_each_link(link, ap, HOST_FIRST) { * We will reach this point for all of the PM events:
ata_for_each_dev(dev, link, ENABLED) * PM_EVENT_SUSPEND (if runtime pm, PM_EVENT_AUTO will also be set)
ata_dev_power_set_standby(dev); * PM_EVENT_FREEZE, and PM_EVENT_HIBERNATE.
*
* We do not want to perform disk spin down for PM_EVENT_FREEZE.
* (Spin down will be performed by the subsequent PM_EVENT_HIBERNATE.)
*/
if (!(ap->pm_mesg.event & PM_EVENT_FREEZE)) {
/* Set all devices attached to the port in standby mode */
ata_for_each_link(link, ap, HOST_FIRST) {
ata_for_each_dev(dev, link, ENABLED)
ata_dev_power_set_standby(dev);
}
} }
/* /*

View File

@ -46,10 +46,11 @@
#define SVWKS_CSB5_REVISION_NEW 0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */ #define SVWKS_CSB5_REVISION_NEW 0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */
#define SVWKS_CSB6_REVISION 0xa0 /* min PCI_REVISION_ID for UDMA4 (A1.0) */ #define SVWKS_CSB6_REVISION 0xa0 /* min PCI_REVISION_ID for UDMA4 (A1.0) */
/* Seagate Barracuda ATA IV Family drives in UDMA mode 5 /*
* can overrun their FIFOs when used with the CSB5 */ * Seagate Barracuda ATA IV Family drives in UDMA mode 5
* can overrun their FIFOs when used with the CSB5.
static const char *csb_bad_ata100[] = { */
static const char * const csb_bad_ata100[] = {
"ST320011A", "ST320011A",
"ST340016A", "ST340016A",
"ST360021A", "ST360021A",
@ -163,10 +164,11 @@ static unsigned int serverworks_osb4_filter(struct ata_device *adev, unsigned in
* @adev: ATA device * @adev: ATA device
* @mask: Mask of proposed modes * @mask: Mask of proposed modes
* *
* Check the blacklist and disable UDMA5 if matched * Check the list of devices with broken UDMA5 and
* disable UDMA5 if matched.
*/ */
static unsigned int serverworks_csb_filter(struct ata_device *adev,
static unsigned int serverworks_csb_filter(struct ata_device *adev, unsigned int mask) unsigned int mask)
{ {
const char *p; const char *p;
char model_num[ATA_ID_PROD_LEN + 1]; char model_num[ATA_ID_PROD_LEN + 1];

View File

@ -128,7 +128,7 @@ static const struct pci_device_id sil_pci_tbl[] = {
static const struct sil_drivelist { static const struct sil_drivelist {
const char *product; const char *product;
unsigned int quirk; unsigned int quirk;
} sil_blacklist [] = { } sil_quirks[] = {
{ "ST320012AS", SIL_QUIRK_MOD15WRITE }, { "ST320012AS", SIL_QUIRK_MOD15WRITE },
{ "ST330013AS", SIL_QUIRK_MOD15WRITE }, { "ST330013AS", SIL_QUIRK_MOD15WRITE },
{ "ST340017AS", SIL_QUIRK_MOD15WRITE }, { "ST340017AS", SIL_QUIRK_MOD15WRITE },
@ -600,8 +600,8 @@ static void sil_thaw(struct ata_port *ap)
* list, and apply the fixups to only the specific * list, and apply the fixups to only the specific
* devices/hosts/firmwares that need it. * devices/hosts/firmwares that need it.
* *
* 20040111 - Seagate drives affected by the Mod15Write bug are blacklisted * 20040111 - Seagate drives affected by the Mod15Write bug are quirked
* The Maxtor quirk is in the blacklist, but I'm keeping the original * The Maxtor quirk is in sil_quirks, but I'm keeping the original
* pessimistic fix for the following reasons... * pessimistic fix for the following reasons...
* - There seems to be less info on it, only one device gleaned off the * - There seems to be less info on it, only one device gleaned off the
* Windows driver, maybe only one is affected. More info would be greatly * Windows driver, maybe only one is affected. More info would be greatly
@ -620,9 +620,9 @@ static void sil_dev_config(struct ata_device *dev)
ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num)); ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
for (n = 0; sil_blacklist[n].product; n++) for (n = 0; sil_quirks[n].product; n++)
if (!strcmp(sil_blacklist[n].product, model_num)) { if (!strcmp(sil_quirks[n].product, model_num)) {
quirks = sil_blacklist[n].quirk; quirks = sil_quirks[n].quirk;
break; break;
} }

View File

@ -104,7 +104,8 @@ static ssize_t bus_attr_show(struct kobject *kobj, struct attribute *attr,
{ {
struct bus_attribute *bus_attr = to_bus_attr(attr); struct bus_attribute *bus_attr = to_bus_attr(attr);
struct subsys_private *subsys_priv = to_subsys_private(kobj); struct subsys_private *subsys_priv = to_subsys_private(kobj);
ssize_t ret = 0; /* return -EIO for reading a bus attribute without show() */
ssize_t ret = -EIO;
if (bus_attr->show) if (bus_attr->show)
ret = bus_attr->show(subsys_priv->bus, buf); ret = bus_attr->show(subsys_priv->bus, buf);
@ -116,7 +117,8 @@ static ssize_t bus_attr_store(struct kobject *kobj, struct attribute *attr,
{ {
struct bus_attribute *bus_attr = to_bus_attr(attr); struct bus_attribute *bus_attr = to_bus_attr(attr);
struct subsys_private *subsys_priv = to_subsys_private(kobj); struct subsys_private *subsys_priv = to_subsys_private(kobj);
ssize_t ret = 0; /* return -EIO for writing a bus attribute without store() */
ssize_t ret = -EIO;
if (bus_attr->store) if (bus_attr->store)
ret = bus_attr->store(subsys_priv->bus, buf, count); ret = bus_attr->store(subsys_priv->bus, buf, count);

View File

@ -791,6 +791,26 @@ static void fw_abort_batch_reqs(struct firmware *fw)
mutex_unlock(&fw_lock); mutex_unlock(&fw_lock);
} }
/*
* Reject firmware file names with ".." path components.
* There are drivers that construct firmware file names from device-supplied
* strings, and we don't want some device to be able to tell us "I would like to
* be sent my firmware from ../../../etc/shadow, please".
*
* Search for ".." surrounded by either '/' or start/end of string.
*
* This intentionally only looks at the firmware name, not at the firmware base
* directory or at symlink contents.
*/
static bool name_contains_dotdot(const char *name)
{
size_t name_len = strlen(name);
return strcmp(name, "..") == 0 || strncmp(name, "../", 3) == 0 ||
strstr(name, "/../") != NULL ||
(name_len >= 3 && strcmp(name+name_len-3, "/..") == 0);
}
/* called from request_firmware() and request_firmware_work_func() */ /* called from request_firmware() and request_firmware_work_func() */
static int static int
_request_firmware(const struct firmware **firmware_p, const char *name, _request_firmware(const struct firmware **firmware_p, const char *name,
@ -811,6 +831,14 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
goto out; goto out;
} }
if (name_contains_dotdot(name)) {
dev_warn(device,
"Firmware load for '%s' refused, path contains '..' component\n",
name);
ret = -EINVAL;
goto out;
}
ret = _request_firmware_prepare(&fw, name, device, buf, size, ret = _request_firmware_prepare(&fw, name, device, buf, size,
offset, opt_flags); offset, opt_flags);
if (ret <= 0) /* error or already assigned */ if (ret <= 0) /* error or already assigned */
@ -886,6 +914,8 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
* @name will be used as $FIRMWARE in the uevent environment and * @name will be used as $FIRMWARE in the uevent environment and
* should be distinctive enough not to be confused with any other * should be distinctive enough not to be confused with any other
* firmware image for this or any other device. * firmware image for this or any other device.
* It must not contain any ".." path components - "foo/bar..bin" is
* allowed, but "foo/../bar.bin" is not.
* *
* Caller must hold the reference count of @device. * Caller must hold the reference count of @device.
* *

View File

@ -3119,7 +3119,7 @@ static int genpd_summary_one(struct seq_file *s,
else else
snprintf(state, sizeof(state), "%s", snprintf(state, sizeof(state), "%s",
status_lookup[genpd->status]); status_lookup[genpd->status]);
seq_printf(s, "%-30s %-50s %u", genpd->name, state, genpd->performance_state); seq_printf(s, "%-30s %-49s %u", genpd->name, state, genpd->performance_state);
/* /*
* Modifications on the list require holding locks on both * Modifications on the list require holding locks on both

View File

@ -361,6 +361,7 @@ ata_rw_frameinit(struct frame *f)
} }
ah->cmdstat = ATA_CMD_PIO_READ | writebit | extbit; ah->cmdstat = ATA_CMD_PIO_READ | writebit | extbit;
dev_hold(t->ifp->nd);
skb->dev = t->ifp->nd; skb->dev = t->ifp->nd;
} }
@ -401,6 +402,8 @@ aoecmd_ata_rw(struct aoedev *d)
__skb_queue_head_init(&queue); __skb_queue_head_init(&queue);
__skb_queue_tail(&queue, skb); __skb_queue_tail(&queue, skb);
aoenet_xmit(&queue); aoenet_xmit(&queue);
} else {
dev_put(f->t->ifp->nd);
} }
return 1; return 1;
} }
@ -483,10 +486,13 @@ resend(struct aoedev *d, struct frame *f)
memcpy(h->dst, t->addr, sizeof h->dst); memcpy(h->dst, t->addr, sizeof h->dst);
memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src); memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src);
dev_hold(t->ifp->nd);
skb->dev = t->ifp->nd; skb->dev = t->ifp->nd;
skb = skb_clone(skb, GFP_ATOMIC); skb = skb_clone(skb, GFP_ATOMIC);
if (skb == NULL) if (skb == NULL) {
dev_put(t->ifp->nd);
return; return;
}
f->sent = ktime_get(); f->sent = ktime_get();
__skb_queue_head_init(&queue); __skb_queue_head_init(&queue);
__skb_queue_tail(&queue, skb); __skb_queue_tail(&queue, skb);
@ -617,6 +623,8 @@ probe(struct aoetgt *t)
__skb_queue_head_init(&queue); __skb_queue_head_init(&queue);
__skb_queue_tail(&queue, skb); __skb_queue_tail(&queue, skb);
aoenet_xmit(&queue); aoenet_xmit(&queue);
} else {
dev_put(f->t->ifp->nd);
} }
} }
@ -1395,6 +1403,7 @@ aoecmd_ata_id(struct aoedev *d)
ah->cmdstat = ATA_CMD_ID_ATA; ah->cmdstat = ATA_CMD_ID_ATA;
ah->lba3 = 0xa0; ah->lba3 = 0xa0;
dev_hold(t->ifp->nd);
skb->dev = t->ifp->nd; skb->dev = t->ifp->nd;
d->rttavg = RTTAVG_INIT; d->rttavg = RTTAVG_INIT;
@ -1404,6 +1413,8 @@ aoecmd_ata_id(struct aoedev *d)
skb = skb_clone(skb, GFP_ATOMIC); skb = skb_clone(skb, GFP_ATOMIC);
if (skb) if (skb)
f->sent = ktime_get(); f->sent = ktime_get();
else
dev_put(t->ifp->nd);
return skb; return skb;
} }

View File

@ -3380,10 +3380,12 @@ void drbd_uuid_new_current(struct drbd_device *device) __must_hold(local)
void drbd_uuid_set_bm(struct drbd_device *device, u64 val) __must_hold(local) void drbd_uuid_set_bm(struct drbd_device *device, u64 val) __must_hold(local)
{ {
unsigned long flags; unsigned long flags;
if (device->ldev->md.uuid[UI_BITMAP] == 0 && val == 0)
return;
spin_lock_irqsave(&device->ldev->md.uuid_lock, flags); spin_lock_irqsave(&device->ldev->md.uuid_lock, flags);
if (device->ldev->md.uuid[UI_BITMAP] == 0 && val == 0) {
spin_unlock_irqrestore(&device->ldev->md.uuid_lock, flags);
return;
}
if (val == 0) { if (val == 0) {
drbd_uuid_move_history(device); drbd_uuid_move_history(device);
device->ldev->md.uuid[UI_HISTORY_START] = device->ldev->md.uuid[UI_BITMAP]; device->ldev->md.uuid[UI_HISTORY_START] = device->ldev->md.uuid[UI_BITMAP];

View File

@ -876,7 +876,7 @@ is_valid_state(struct drbd_device *device, union drbd_state ns)
ns.disk == D_OUTDATED) ns.disk == D_OUTDATED)
rv = SS_CONNECTED_OUTDATES; rv = SS_CONNECTED_OUTDATES;
else if ((ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) && else if (nc && (ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) &&
(nc->verify_alg[0] == 0)) (nc->verify_alg[0] == 0))
rv = SS_NO_VERIFY_ALG; rv = SS_NO_VERIFY_ALG;

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