mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-23 07:23:12 +02:00
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:
commit
6a3e72e9c6
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -133,7 +133,6 @@ GTAGS
|
||||||
# id-utils files
|
# id-utils files
|
||||||
ID
|
ID
|
||||||
|
|
||||||
*.orig
|
|
||||||
*~
|
*~
|
||||||
\#*#
|
\#*#
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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::
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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 |
|
||||||
|
|
|
@ -23,7 +23,6 @@ properties:
|
||||||
- ak8963
|
- ak8963
|
||||||
- ak09911
|
- ak09911
|
||||||
- ak09912
|
- ak09912
|
||||||
- ak09916
|
|
||||||
deprecated: true
|
deprecated: true
|
||||||
|
|
||||||
reg:
|
reg:
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
>;
|
>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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]);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -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>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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) \
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) \
|
||||||
|
|
|
@ -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__ */
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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, ®s->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)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
10
block/blk.h
10
block/blk.h
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>". */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
31
crypto/xor.c
31
crypto/xor.c
|
@ -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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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++) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 = ®_res->cpc_entry.reg;
|
struct cpc_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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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 = {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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
Loading…
Reference in New Issue
Block a user