4.4.200-stable review
Subsystems (2)
Greg Kroah-Hartman
maintainercover 4.4.200-stable review
This is the start of the stable review cycle for the 4.4.200 release. There are 75 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun 10 Nov 2019 05:42:11 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.200-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.4.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 4.4.200-rc1
zhangyi (F) <[email protected]>
fs/dcache: move security_d_instantiate() behind attaching dentry to inode
Petr Vorel <[email protected]>
alarmtimer: Change remaining ENOTSUPP to EOPNOTSUPP
Russell King <[email protected]>
ARM: fix the cockup in the previous patch
Russell King <[email protected]>
ARM: ensure that processor vtables is not lost after boot
Russell King <[email protected]>
ARM: spectre-v2: per-CPU vtables to work around big.Little systems
Russell King <[email protected]>
ARM: add PROC_VTABLE and PROC_TABLE macros
Russell King <[email protected]>
ARM: clean up per-processor check_bugs method call
Russell King <[email protected]>
ARM: split out processor lookup
Russell King <[email protected]>
ARM: make lookup_processor_type() non-__init
Julien Thierry <[email protected]>
ARM: 8810/1: vfp: Fix wrong assignement to ufp_exc
Julien Thierry <[email protected]>
ARM: 8796/1: spectre-v1,v1.1: provide helpers for address sanitization
Julien Thierry <[email protected]>
ARM: 8795/1: spectre-v1.1: use put_user() for __put_user()
Julien Thierry <[email protected]>
ARM: 8794/1: uaccess: Prevent speculative use of the current addr_limit
Julien Thierry <[email protected]>
ARM: 8793/1: signal: replace __put_user_error with __put_user
Julien Thierry <[email protected]>
ARM: 8792/1: oabi-compat: copy oabi events using __copy_to_user()
Julien Thierry <[email protected]>
ARM: 8791/1: vfp: use __copy_to_user() when saving VFP state
Julien Thierry <[email protected]>
ARM: 8789/1: signal: copy registers using __copy_to_user()
Russell King <[email protected]>
ARM: spectre-v1: mitigate user accesses
Russell King <[email protected]>
ARM: spectre-v1: use get_user() for __get_user()
Russell King <[email protected]>
ARM: use __inttype() in get_user()
Russell King <[email protected]>
ARM: oabi-compat: copy semops using __copy_from_user()
Russell King <[email protected]>
ARM: vfp: use __copy_from_user() when restoring VFP state
Russell King <[email protected]>
ARM: signal: copy registers using __copy_from_user()
Russell King <[email protected]>
ARM: spectre-v1: fix syscall entry
Russell King <[email protected]>
ARM: spectre-v1: add array_index_mask_nospec() implementation
Russell King <[email protected]>
ARM: spectre-v1: add speculation barrier (csdb) macros
Russell King <[email protected]>
ARM: spectre-v2: warn about incorrect context switching functions
Russell King <[email protected]>
ARM: spectre-v2: add firmware based hardening
Russell King <[email protected]>
ARM: spectre-v2: harden user aborts in kernel space
Russell King <[email protected]>
ARM: spectre-v2: add Cortex A8 and A15 validation of the IBE bit
Russell King <[email protected]>
ARM: spectre-v2: harden branch predictor on context switches
Russell King <[email protected]>
ARM: spectre: add Kconfig symbol for CPUs vulnerable to Spectre
Russell King <[email protected]>
ARM: bugs: add support for per-processor bug checking
Russell King <[email protected]>
ARM: bugs: hook processor bug checking into SMP and suspend paths
Russell King <[email protected]>
ARM: bugs: prepare processor bug infrastructure
Russell King <[email protected]>
ARM: add more CPU part numbers for Cortex and Brahma B15 CPUs
Marc Zyngier <[email protected]>
arm/arm64: smccc-1.1: Handle function result as parameters
Marc Zyngier <[email protected]>
arm/arm64: smccc-1.1: Make return values unsigned long
Marc Zyngier <[email protected]>
arm/arm64: smccc: Add SMCCC-specific return codes
Marc Zyngier <[email protected]>
arm/arm64: smccc: Implement SMCCC v1.1 inline primitive
Marc Zyngier <[email protected]>
arm/arm64: smccc: Make function identifiers an unsigned quantity
Marc Zyngier <[email protected]>
firmware/psci: Expose SMCCC version through psci_ops
Marc Zyngier <[email protected]>
firmware/psci: Expose PSCI conduit
Marc Zyngier <[email protected]>
arm64: KVM: Report SMCCC_ARCH_WORKAROUND_1 BP hardening support
Marc Zyngier <[email protected]>
arm/arm64: KVM: Advertise SMCCC v1.1
Vladimir Murzin <[email protected]>
ARM: Move system register accessors to asm/cp15.h
Russell King <[email protected]>
ARM: uaccess: remove put_user() code duplication
Jens Wiklander <[email protected]>
ARM: 8481/2: drivers: psci: replace psci firmware calls
Jens Wiklander <[email protected]>
ARM: 8480/2: arm64: add implementation for arm-smccc
Jens Wiklander <[email protected]>
ARM: 8479/2: add implementation for arm-smccc
Jens Wiklander <[email protected]>
ARM: 8478/2: arm/arm64: add arm-smccc
Andrey Ryabinin <[email protected]>
ARM: 8051/1: put_user: fix possible data corruption in put_user
Jeffrey Hugo <[email protected]>
dmaengine: qcom: bam_dma: Fix resource leak
Eric Dumazet <[email protected]>
net/flow_dissector: switch to siphash
Eric Dumazet <[email protected]>
inet: stop leaking jiffies on the wire
Eran Ben Elisha <[email protected]>
net/mlx4_core: Dynamically set guaranteed amount of counters per VF
Xin Long <[email protected]>
vxlan: check tun_info options_len properly
Eric Dumazet <[email protected]>
net: add READ_ONCE() annotation in __skb_wait_for_more_packets()
zhanglin <[email protected]>
net: Zeroing the structure ethtool_wolinfo in ethtool_get_wol()
Jiangfeng Xiao <[email protected]>
net: hisilicon: Fix ping latency when deal with high throughput
Tejun Heo <[email protected]>
net: fix sk_page_frag() recursion from memory reclaim
Eric Dumazet <[email protected]>
dccp: do not leak jiffies on the wire
Dave Wysochanski <[email protected]>
cifs: Fix cifsInodeInfo lock_sem deadlock when reconnect occurs
Jonas Gorski <[email protected]>
MIPS: bmips: mark exception vectors as char arrays
Navid Emamdoost <[email protected]>
of: unittest: fix memory leak in unittest_data_add
Bodo Stroesser <[email protected]>
scsi: target: core: Do not overwrite CDB byte 1
Yunfeng Ye <[email protected]>
perf kmem: Fix memory leak in compact_gfp_flags()
Thomas Bogendoerfer <[email protected]>
scsi: fix kconfig dependency warning related to 53C700_LE_ON_BE
Thomas Bogendoerfer <[email protected]>
scsi: sni_53c710: fix compilation error
Russell King <[email protected]>
ARM: mm: fix alignment handler faults under memory pressure
Adam Ford <[email protected]>
ARM: dts: logicpd-torpedo-som: Remove twl_keypad
Robin Murphy <[email protected]>
ASoc: rockchip: i2s: Fix RPM imbalance
Yizhuo <[email protected]>
regulator: pfuze100-regulator: Variable "val" in pfuze100_regulator_probe() could be uninitialized
Axel Lin <[email protected]>
regulator: ti-abb: Fix timeout in ti_abb_wait_txdone/ti_abb_clear_all_txdone
Seth Forshee <[email protected]>
kbuild: add -fcf-protection=none when using retpoline flags
-------------
Diffstat:
Makefile | 10 +- arch/arm/Kconfig | 3 +- arch/arm/boot/dts/logicpd-torpedo-som.dtsi | 4 + arch/arm/include/asm/arch_gicv3.h | 27 +- arch/arm/include/asm/assembler.h | 23 ++ arch/arm/include/asm/barrier.h | 34 +++ arch/arm/include/asm/bugs.h | 6 +- arch/arm/include/asm/cp15.h | 18 ++ arch/arm/include/asm/cputype.h | 9 + arch/arm/include/asm/proc-fns.h | 65 ++++- arch/arm/include/asm/system_misc.h | 15 ++ arch/arm/include/asm/thread_info.h | 8 +- arch/arm/include/asm/uaccess.h | 177 ++++++++----- arch/arm/kernel/Makefile | 4 +- arch/arm/kernel/armksyms.c | 6 + arch/arm/kernel/bugs.c | 18 ++ arch/arm/kernel/entry-common.S | 18 +- arch/arm/kernel/entry-header.S | 25 ++ arch/arm/kernel/head-common.S | 6 +- arch/arm/kernel/psci-call.S | 31 --- arch/arm/kernel/setup.c | 40 +-- arch/arm/kernel/signal.c | 125 ++++----- arch/arm/kernel/smccc-call.S | 62 +++++ arch/arm/kernel/smp.c | 36 +++ arch/arm/kernel/suspend.c | 2 + arch/arm/kernel/sys_oabi-compat.c | 16 +- arch/arm/lib/copy_from_user.S | 5 + arch/arm/mm/Kconfig | 23 ++ arch/arm/mm/Makefile | 2 +- arch/arm/mm/alignment.c | 44 +++- arch/arm/mm/fault.c | 3 + arch/arm/mm/proc-macros.S | 13 +- arch/arm/mm/proc-v7-2level.S | 6 - arch/arm/mm/proc-v7-bugs.c | 161 ++++++++++++ arch/arm/mm/proc-v7.S | 154 ++++++++--- arch/arm/vfp/vfpmodule.c | 37 ++- arch/arm64/Kconfig | 1 + arch/arm64/kernel/Makefile | 4 +- arch/arm64/kernel/arm64ksyms.c | 5 + arch/arm64/kernel/asm-offsets.c | 3 + arch/arm64/kernel/psci-call.S | 28 -- arch/arm64/kernel/smccc-call.S | 43 ++++ arch/mips/bcm63xx/prom.c | 2 +- arch/mips/include/asm/bmips.h | 10 +- arch/mips/kernel/smp-bmips.c | 8 +- drivers/dma/qcom_bam_dma.c | 14 + drivers/firmware/Kconfig | 3 + drivers/firmware/psci.c | 78 +++++- drivers/net/ethernet/hisilicon/hip04_eth.c | 15 +- .../net/ethernet/mellanox/mlx4/resource_tracker.c | 42 +-- drivers/net/vxlan.c | 5 +- drivers/of/unittest.c | 1 + drivers/regulator/pfuze100-regulator.c | 8 +- drivers/regulator/ti-abb-regulator.c | 26 +- drivers/scsi/Kconfig | 2 +- drivers/scsi/sni_53c710.c | 4 +- drivers/target/target_core_device.c | 21 -- fs/cifs/cifsglob.h | 5 + fs/cifs/cifsproto.h | 1 + fs/cifs/file.c | 23 +- fs/cifs/smb2file.c | 2 +- fs/dcache.c | 2 +- include/linux/arm-smccc.h | 283 +++++++++++++++++++++ include/linux/gfp.h | 23 ++ include/linux/psci.h | 13 + include/linux/skbuff.h | 3 +- include/net/flow_dissector.h | 3 +- include/net/sock.h | 11 +- kernel/time/alarmtimer.c | 4 +- net/core/datagram.c | 2 +- net/core/ethtool.c | 4 +- net/core/flow_dissector.c | 48 ++-- net/dccp/ipv4.c | 4 +- net/ipv4/datagram.c | 2 +- net/ipv4/tcp_ipv4.c | 4 +- net/sched/sch_fq_codel.c | 6 +- net/sched/sch_hhf.c | 8 +- net/sched/sch_sfb.c | 13 +- net/sched/sch_sfq.c | 14 +- net/sctp/socket.c | 2 +- sound/soc/rockchip/rockchip_i2s.c | 2 +- tools/perf/builtin-kmem.c | 1 + 82 files changed, 1556 insertions(+), 486 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/75 kbuild: add -fcf-protection=none when using retpoline flags
From: Seth Forshee <[email protected]>
[ Upstream commit 29be86d7f9cb18df4123f309ac7857570513e8bc ]
The gcc -fcf-protection=branch option is not compatible with -mindirect-branch=thunk-extern. The latter is used when CONFIG_RETPOLINE is selected, and this will fail to build with a gcc which has -fcf-protection=branch enabled by default. Adding -fcf-protection=none when building with retpoline enabled prevents such build failures.
--- Makefile | 6 ++++++ 1 file changed, 6 insertions(+)
Makefile +6 -0
@@ -823,6 +823,12 @@ KBUILD_CFLAGS += $(call cc-option,-Werror=strict-prototypes) # Prohibit date/time macros, which would make the build non-deterministic KBUILD_CFLAGS += $(call cc-option,-Werror=date-time) +# ensure -fcf-protection is disabled when using retpoline as it is +# incompatible with -mindirect-branch=thunk-extern +ifdef CONFIG_RETPOLINE +KBUILD_CFLAGS += $(call cc-option,-fcf-protection=none) +endif + # use the deterministic mode of AR if available KBUILD_ARFLAGS := $(call ar-option,D)
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 2/75 regulator: ti-abb: Fix timeout in ti_abb_wait_txdone/ti_abb_clear_all_txdone
In reply to Greg Kroah-HartmanFrom: Axel Lin <[email protected]>
[ Upstream commit f64db548799e0330897c3203680c2ee795ade518 ]
ti_abb_wait_txdone() may return -ETIMEDOUT when ti_abb_check_txdone() returns true in the latest iteration of the while loop because the timeout value is abb->settling_time + 1. Similarly, ti_abb_clear_all_txdone() may return -ETIMEDOUT when ti_abb_check_txdone() returns false in the latest iteration of the while loop. Fix it.
--- drivers/regulator/ti-abb-regulator.c | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-)
drivers/regulator/ti-abb-regulator.c +8 -18
@@ -173,19 +173,14 @@ static int ti_abb_wait_txdone(struct device *dev, struct ti_abb *abb)while (timeout++ <= abb->settling_time) { status =ti_abb_check_txdone (abb);if (status) -break ; +return 0 ;udelay (1 ); } -if (timeout > abb->settling_time) { -dev_warn_ratelimited (dev, -"%s:TRANXDONE timeout(%duS) int=0x%08x\n" , - __func__, timeout,readl (abb->int_base)); -return -ETIMEDOUT ; - } - -return 0 ; +dev_warn_ratelimited (dev,"%s:TRANXDONE timeout(%duS) int=0x%08x\n" , + __func__, timeout,readl (abb->int_base)); +return -ETIMEDOUT ; }/**
@@ -205,19 +200,14 @@ static int ti_abb_clear_all_txdone(struct device *dev, const struct ti_abb *abb) status =ti_abb_check_txdone (abb);if (!status) -break ; +return 0 ;udelay (1 ); } -if (timeout > abb->settling_time) { -dev_warn_ratelimited (dev, -"%s:TRANXDONE timeout(%duS) int=0x%08x\n" , - __func__, timeout,readl (abb->int_base)); -return -ETIMEDOUT ; - } - -return 0 ; +dev_warn_ratelimited (dev,"%s:TRANXDONE timeout(%duS) int=0x%08x\n" , + __func__, timeout,readl (abb->int_base)); +return -ETIMEDOUT ; }/**
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 3/75 regulator: pfuze100-regulator: Variable "val" in pfuze100_regulator_probe() could be uninitialized
In reply to Greg Kroah-HartmanFrom: Yizhuo <[email protected]>
[ Upstream commit 1252b283141f03c3dffd139292c862cae10e174d ]
In function pfuze100_regulator_probe(), variable "val" could be initialized if regmap_read() fails. However, "val" is used to decide the control flow later in the if statement, which is potentially unsafe.
--- drivers/regulator/pfuze100-regulator.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/regulator/pfuze100-regulator.c +7 -1
@@ -609,7 +609,13 @@ static int pfuze100_regulator_probe(struct i2c_client *client,/* SW2~SW4 high bit check and modify the voltage value table */ if (i >= sw_check_start && i <= sw_check_end) { -regmap_read (pfuze_chip->regmap, desc->vsel_reg, &val); + ret =regmap_read (pfuze_chip->regmap, + desc->vsel_reg, &val); +if (ret) { +dev_err (&client->dev,"Fails to read from the register.\n" ); +return ret; + } +if (val & sw_hi) {if (pfuze_chip->chip_id ==PFUZE3000 ) { desc->volt_table = pfuze3000_sw2hi;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 4/75 ASoc: rockchip: i2s: Fix RPM imbalance
In reply to Greg Kroah-HartmanFrom: Robin Murphy <[email protected]>
[ Upstream commit b1e620e7d32f5aad5353cc3cfc13ed99fea65d3a ]
If rockchip_pcm_platform_register() fails, e.g. upon deferring to wait for an absent DMA channel, we return without disabling RPM, which makes subsequent re-probe attempts scream with errors about the unbalanced enable. Don't do that.
--- sound/soc/rockchip/rockchip_i2s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/rockchip/rockchip_i2s.c +1 -1
@@ -530,7 +530,7 @@ static int rockchip_i2s_probe(struct platform_device *pdev) ret =devm_snd_dmaengine_pcm_register (&pdev->dev,NULL ,0 );if (ret) {dev_err (&pdev->dev,"Could not register PCM\n" ); -return ret; + goto err_suspend; }return 0 ;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 5/75 ARM: dts: logicpd-torpedo-som: Remove twl_keypad
In reply to Greg Kroah-HartmanFrom: Adam Ford <[email protected]>
[ Upstream commit 6b512b0ee091edcb8e46218894e4c917d919d3dc ]
The TWL4030 used on the Logit PD Torpedo SOM does not have the keypad pins routed. This patch disables the twl_keypad driver to remove some splat during boot:
twl4030_keypad 48070000.i2c:twl@48:keypad: missing or malformed property linux,keymap: -22 twl4030_keypad 48070000.i2c:twl@48:keypad: Failed to build keymaptwl4030_keypad: probe of 48070000.i2c:twl@48:keypad failed with error -22
--- arch/arm/boot/dts/logicpd-torpedo-som.dtsi | 4 ++++ 1 file changed, 4 insertions(+)
arch/arm/boot/dts/logicpd-torpedo-som.dtsi +4 -0
@@ -169,3 +169,7 @@ &twl_gpio { ti,use-leds; }; + +&twl_keypad { + status = "disabled"; +};
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 6/75 ARM: mm: fix alignment handler faults under memory pressure
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
[ Upstream commit 67e15fa5b487adb9b78a92789eeff2d6ec8f5cee ]
When the system has high memory pressure, the page containing the instruction may be paged out. Using probe_kernel_address() means that if the page is swapped out, the resulting page fault will not be handled because page faults are disabled by this function.
Use get_user() to read the instruction instead.
--- arch/arm/mm/alignment.c | 44 +++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-)
arch/arm/mm/alignment.c +36 -8
@@ -767,6 +767,36 @@ do_alignment_t32_to_handler(unsigned long *pinstr, struct pt_regs *regs,return NULL ; } +static int alignment_get_arm (struct pt_regs *regs,u32 *ip,unsigned long *inst) +{ +u32 instr =0 ; +int fault; + +if (user_mode (regs)) + fault =get_user (instr, ip); +else + fault =probe_kernel_address (ip, instr); + + *inst =__mem_to_opcode_arm (instr); + +return fault; +} + +static int alignment_get_thumb (struct pt_regs *regs,u16 *ip,u16 *inst) +{ +u16 instr =0 ; +int fault; + +if (user_mode (regs)) + fault =get_user (instr, ip); +else + fault =probe_kernel_address (ip, instr); + + *inst =__mem_to_opcode_thumb16 (instr); + +return fault; +} +static int do_alignment (unsigned long addr,unsigned int fsr,struct pt_regs *regs) {
@@ -774,10 +804,10 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)unsigned long instr =0 , instrptr;int (*handler)(unsigned long addr,unsigned long instr,struct pt_regs *regs);unsigned int type; -unsigned int fault;u16 tinstr =0 ;int isize =4 ;int thumb2_32b =0 ; +int fault;if (interrupts_enabled (regs))local_irq_enable ();
@@ -786,15 +816,14 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)if (thumb_mode (regs)) {u16 *ptr = (u16 *)(instrptr & ~1 ); - fault =probe_kernel_address (ptr, tinstr); - tinstr =__mem_to_opcode_thumb16 (tinstr); + + fault =alignment_get_thumb (regs, ptr, &tinstr);if (!fault) {if (cpu_architecture () >= CPU_ARCH_ARMv7 &&IS_T32 (tinstr)) {/* Thumb-2 32-bit */ -u16 tinst2 =0 ; - fault =probe_kernel_address (ptr +1 , tinst2); - tinst2 =__mem_to_opcode_thumb16 (tinst2); +u16 tinst2; + fault =alignment_get_thumb (regs, ptr +1 , &tinst2); instr =__opcode_thumb32_compose (tinstr, tinst2); thumb2_32b =1 ; }else {
@@ -803,8 +832,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) } } }else { - fault =probe_kernel_address ((void *)instrptr, instr); - instr =__mem_to_opcode_arm (instr); + fault =alignment_get_arm (regs, (void *)instrptr, &instr); }if (fault) {
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 7/75 scsi: sni_53c710: fix compilation error
In reply to Greg Kroah-HartmanFrom: Thomas Bogendoerfer <[email protected]>
[ Upstream commit 0ee6211408a8e939428f662833c7301394125b80 ]
Drop out memory dev_printk() with wrong device pointer argument.
[mkp: typo]
--- drivers/scsi/sni_53c710.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/scsi/sni_53c710.c +1 -3
@@ -78,10 +78,8 @@ static int snirm710_probe(struct platform_device *dev) base = res->start; hostdata =kzalloc (sizeof (*hostdata),GFP_KERNEL ); -if (!hostdata) { -dev_printk (KERN_ERR , dev,"Failed to allocate host data\n" ); +if (!hostdata)return -ENOMEM ; - } hostdata->dev = &dev->dev;dma_set_mask (&dev->dev,DMA_BIT_MASK (32 ));
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 8/75 scsi: fix kconfig dependency warning related to 53C700_LE_ON_BE
In reply to Greg Kroah-HartmanFrom: Thomas Bogendoerfer <[email protected]>
[ Upstream commit 8cbf0c173aa096dda526d1ccd66fc751c31da346 ]
When building a kernel with SCSI_SNI_53C710 enabled, Kconfig warns:
WARNING: unmet direct dependencies detected for 53C700_LE_ON_BE
Depends on [n]: SCSI_LOWLEVEL [=y] && SCSI [=y] && SCSI_LASI700 [=n] Selected by [y]:
- SCSI_SNI_53C710 [=y] && SCSI_LOWLEVEL [=y] && SNI_RM [=y] && SCSI [=y]
Add the missing depends SCSI_SNI_53C710 to 53C700_LE_ON_BE to fix it.
--- drivers/scsi/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/Kconfig +1 -1
@@ -1013,7 +1013,7 @@ config SCSI_SNI_53C710 config 53C700_LE_ON_BE bool - depends on SCSI_LASI700 + depends on SCSI_LASI700 || SCSI_SNI_53C710 default y config SCSI_STEX
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 9/75 perf kmem: Fix memory leak in compact_gfp_flags()
In reply to Greg Kroah-HartmanFrom: Yunfeng Ye <[email protected]>
[ Upstream commit 1abecfcaa7bba21c9985e0136fa49836164dd8fd ]
The memory @orig_flags is allocated by strdup(), it is freed on the normal path, but leak to free on the error path.
Fix this by adding free(orig_flags) on the error path.
--- tools/perf/builtin-kmem.c | 1 + 1 file changed, 1 insertion(+)
tools/perf/builtin-kmem.c +1 -0
@@ -664,6 +664,7 @@ static char *compact_gfp_flags(char *gfp_flags) new =realloc (new_flags, len +strlen (cpt) +2 );if (new ==NULL ) {free (new_flags); +free (orig_flags);return NULL ; }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 10/75 scsi: target: core: Do not overwrite CDB byte 1
In reply to Greg Kroah-HartmanFrom: Bodo Stroesser <[email protected]>
[ Upstream commit 27e84243cb63601a10e366afe3e2d05bb03c1cb5 ]
passthrough_parse_cdb() - used by TCMU and PSCSI - attepts to reset the LUN field of SCSI-2 CDBs (bits 5,6,7 of byte 1). The current code is wrong as for newer commands not having the LUN field it overwrites relevant command bits (e.g. for SECURITY PROTOCOL IN / OUT). We think this code was unnecessary from the beginning or at least it is no longer useful. So we remove it entirely.
--- drivers/target/target_core_device.c | 21 --------------------- 1 file changed, 21 deletions(-)
drivers/target/target_core_device.c +0 -21
@@ -1056,27 +1056,6 @@ passthrough_parse_cdb(struct se_cmd *cmd, {unsigned char *cdb = cmd->t_task_cdb; -/* -* Clear a lun set in the cdb if the initiator talking to use spoke -* and old standards version, as we can't assume the underlying device -* won't choke up on it. -*/ -switch (cdb[0 ]) { -case READ_10 :/* SBC - RDProtect */ -case READ_12 :/* SBC - RDProtect */ -case READ_16 :/* SBC - RDProtect */ -case SEND_DIAGNOSTIC :/* SPC - SELF-TEST Code */ -case VERIFY :/* SBC - VRProtect */ -case VERIFY_16 :/* SBC - VRProtect */ -case WRITE_VERIFY :/* SBC - VRProtect */ -case WRITE_VERIFY_12 :/* SBC - VRProtect */ -case MAINTENANCE_IN :/* SPC - Parameter Data Format for SA RTPG */ -break ; -default : - cdb[1 ] &=0x1f ;/* clear logical unit number */ -break ; - } -/* * For REPORT LUNS we always need to emulate the response, for everything * else, pass it up.
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 11/75 of: unittest: fix memory leak in unittest_data_add
In reply to Greg Kroah-HartmanFrom: Navid Emamdoost <[email protected]>
[ Upstream commit e13de8fe0d6a51341671bbe384826d527afe8d44 ]
In unittest_data_add, a copy buffer is created via kmemdup. This buffer is leaked if of_fdt_unflatten_tree fails. The release for the unittest_data buffer is added.
--- drivers/of/unittest.c | 1 + 1 file changed, 1 insertion(+)
drivers/of/unittest.c +1 -0
@@ -924,6 +924,7 @@ static int __init unittest_data_add(void)of_fdt_unflatten_tree (unittest_data, &unittest_data_node);if (!unittest_data_node) {pr_warn ("%s: No tree to attach; not running tests\n" , __func__); +kfree (unittest_data);return -ENODATA ; }of_node_set_flag (unittest_data_node,OF_DETACHED );
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 12/75 MIPS: bmips: mark exception vectors as char arrays
In reply to Greg Kroah-HartmanFrom: Jonas Gorski <[email protected]>
[ Upstream commit e4f5cb1a9b27c0f94ef4f5a0178a3fde2d3d0e9e ]
The vectors span more than one byte, so mark them as arrays.
Fixes the following build error when building when using GCC 8.3:
In file included from ./include/linux/string.h:19,
from ./include/linux/bitmap.h:9,
from ./include/linux/cpumask.h:12,
from ./arch/mips/include/asm/processor.h:15,
from ./arch/mips/include/asm/thread_info.h:16,
from ./include/linux/thread_info.h:38,
from ./include/asm-generic/preempt.h:5,
from ./arch/mips/include/generated/asm/preempt.h:1,
from ./include/linux/preempt.h:81,
from ./include/linux/spinlock.h:51,
from ./include/linux/mmzone.h:8,
from ./include/linux/bootmem.h:8,
from arch/mips/bcm63xx/prom.c:10:
arch/mips/bcm63xx/prom.c: In function 'prom_init':
./arch/mips/include/asm/string.h:162:11: error: '__builtin_memcpy' forming offset [2, 32] is out of the bounds [0, 1] of object 'bmips_smp_movevec' with type 'char' [-Werror=array-bounds]
__ret = __builtin_memcpy((dst), (src), __len); \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~arch/mips/bcm63xx/prom.c:97:3: note: in expansion of macro 'memcpy'
memcpy((void *)0xa0000200, &bmips_smp_movevec, 0x20);
^~~~~~
In file included from arch/mips/bcm63xx/prom.c:14:./arch/mips/include/asm/bmips.h:80:13: note: 'bmips_smp_movevec' declared here
extern char bmips_smp_movevec;
--- arch/mips/bcm63xx/prom.c | 2 +- arch/mips/include/asm/bmips.h | 10 +++++----- arch/mips/kernel/smp-bmips.c | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-)
arch/mips/bcm63xx/prom.c +1 -1
@@ -84,7 +84,7 @@ void __init prom_init(void)* Here we will start up CPU1 in the background and ask it to * reconfigure itself then go back to sleep. */ -memcpy ((void *)0xa0000200 , &bmips_smp_movevec,0x20 ); +memcpy ((void *)0xa0000200 , bmips_smp_movevec,0x20 );__sync ();set_c0_cause (C_SW0 );cpumask_set_cpu (1 , &bmips_booted_mask);
arch/mips/include/asm/bmips.h +5 -5
@@ -75,11 +75,11 @@ static inline int register_bmips_smp_ops(void)#endif } -extern char bmips_reset_nmi_vec; -extern char bmips_reset_nmi_vec_end; -extern char bmips_smp_movevec; -extern char bmips_smp_int_vec; -extern char bmips_smp_int_vec_end; +extern char bmips_reset_nmi_vec[]; +extern char bmips_reset_nmi_vec_end[]; +extern char bmips_smp_movevec[]; +extern char bmips_smp_int_vec[]; +extern char bmips_smp_int_vec_end[];extern int bmips_smp_enabled;extern int bmips_cpu_offset;
arch/mips/kernel/smp-bmips.c +4 -4
@@ -451,10 +451,10 @@ static void bmips_wr_vec(unsigned long dst, char *start, char *end)static inline void bmips_nmi_handler_setup (void ) { -bmips_wr_vec (BMIPS_NMI_RESET_VEC , &bmips_reset_nmi_vec, - &bmips_reset_nmi_vec_end); -bmips_wr_vec (BMIPS_WARM_RESTART_VEC , &bmips_smp_int_vec, - &bmips_smp_int_vec_end); +bmips_wr_vec (BMIPS_NMI_RESET_VEC , bmips_reset_nmi_vec, + bmips_reset_nmi_vec_end); +bmips_wr_vec (BMIPS_WARM_RESTART_VEC , bmips_smp_int_vec, + bmips_smp_int_vec_end); }struct reset_vec_info {
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 13/75 cifs: Fix cifsInodeInfo lock_sem deadlock when reconnect occurs
In reply to Greg Kroah-HartmanFrom: Dave Wysochanski <[email protected]>
[ Upstream commit d46b0da7a33dd8c99d969834f682267a45444ab3 ]
There's a deadlock that is possible and can easily be seen with a test where multiple readers open/read/close of the same file and a disruption occurs causing reconnect. The deadlock is due a reader thread inside cifs_strict_readv calling down_read and obtaining lock_sem, and then after reconnect inside cifs_reopen_file calling down_read a second time. If in between the two down_read calls, a down_write comes from another process, deadlock occurs.
CPU0 CPU1
---- ----
cifs_strict_readv()
down_read(&cifsi->lock_sem);
_cifsFileInfo_put
OR
cifs_new_fileinfo
down_write(&cifsi->lock_sem);cifs_reopen_file()
down_read(&cifsi->lock_sem);
Fix the above by changing all down_write(lock_sem) calls to down_write_trylock(lock_sem)/msleep() loop, which in turn makes the second down_read call benign since it will never block behind the writer while holding lock_sem.
--- fs/cifs/cifsglob.h | 5 +++++ fs/cifs/cifsproto.h | 1 + fs/cifs/file.c | 23 +++++++++++++++-------- fs/cifs/smb2file.c | 2 +- 4 files changed, 22 insertions(+), 9 deletions(-)
fs/cifs/cifsglob.h +5 -0
@@ -1152,6 +1152,11 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file);struct cifsInodeInfo {bool can_cache_brlcks;struct list_head llist;/* locks helb by this inode */ +/* +* NOTE: Some code paths call down_read(lock_sem) twice, so +* we must always use use cifs_down_write() instead of down_write() +* for this semaphore to avoid deadlocks. +*/ struct rw_semaphore lock_sem;/* protect the fields above */ /* BB add in lists for dirty pages i.e. write caching info for oplock */ struct list_head openFileList;
fs/cifs/cifsproto.h +1 -0
@@ -138,6 +138,7 @@ extern int cifs_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock, const unsigned int xid);extern int cifs_push_mandatory_locks (struct cifsFileInfo *cfile); +extern void cifs_down_write (struct rw_semaphore *sem); extern struct cifsFileInfo *cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, struct tcon_link *tlink,
fs/cifs/file.c +15 -8
@@ -280,6 +280,13 @@ cifs_has_mand_locks(struct cifsInodeInfo *cinode)return has_locks; } +void +cifs_down_write (struct rw_semaphore *sem) +{ +while (!down_write_trylock (sem)) +msleep (10 ); +} +struct cifsFileInfo *cifs_new_fileinfo (struct cifs_fid *fid,struct file *file,struct tcon_link *tlink,__u32 oplock)
@@ -305,7 +312,7 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,INIT_LIST_HEAD (&fdlocks->locks); fdlocks->cfile = cfile; cfile->llist = fdlocks; -down_write (&cinode->lock_sem); +cifs_down_write (&cinode->lock_sem);list_add (&fdlocks->llist, &cinode->llist);up_write (&cinode->lock_sem);
@@ -438,7 +445,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)* Delete any outstanding lock records. We'll lose them when the file * is closed anyway. */ -down_write (&cifsi->lock_sem); +cifs_down_write (&cifsi->lock_sem);list_for_each_entry_safe (li, tmp, &cifs_file->llist->locks, llist) {list_del (&li->llist);cifs_del_lock_waiters (li);
@@ -947,7 +954,7 @@ static void cifs_lock_add(struct cifsFileInfo *cfile, struct cifsLockInfo *lock) { struct cifsInodeInfo *cinode = CIFS_I(d_inode(cfile->dentry)); -down_write (&cinode->lock_sem); +cifs_down_write (&cinode->lock_sem);list_add_tail (&lock->llist, &cfile->llist->locks);up_write (&cinode->lock_sem); }
@@ -969,7 +976,7 @@ cifs_lock_add_if(struct cifsFileInfo *cfile, struct cifsLockInfo *lock, try_again: exist = false; -down_write (&cinode->lock_sem); +cifs_down_write (&cinode->lock_sem); exist =cifs_find_lock_conflict (cfile, lock->offset, lock->length, lock->type, &conf_lock,CIFS_LOCK_OP );
@@ -991,7 +998,7 @@ cifs_lock_add_if(struct cifsFileInfo *cfile, struct cifsLockInfo *lock, (lock->blist.next == &lock->blist));if (!rc) goto try_again; -down_write (&cinode->lock_sem); +cifs_down_write (&cinode->lock_sem);list_del_init (&lock->blist); }
@@ -1044,7 +1051,7 @@ cifs_posix_lock_set(struct file *file, struct file_lock *flock)return rc; try_again: -down_write (&cinode->lock_sem); +cifs_down_write (&cinode->lock_sem);if (!cinode->can_cache_brlcks) {up_write (&cinode->lock_sem);return rc;
@@ -1242,7 +1249,7 @@ cifs_push_locks(struct cifsFileInfo *cfile)int rc =0 ;/* we are going to update can_cache_brlcks here - need a write access */ -down_write (&cinode->lock_sem); +cifs_down_write (&cinode->lock_sem);if (!cinode->can_cache_brlcks) {up_write (&cinode->lock_sem);return rc;
@@ -1430,7 +1437,7 @@ cifs_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock,if (!buf)return -ENOMEM ; -down_write (&cinode->lock_sem); +cifs_down_write (&cinode->lock_sem);for (i =0 ; i <2 ; i++) { cur = buf; num =0 ;
fs/cifs/smb2file.c +1 -1
@@ -138,7 +138,7 @@ smb2_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock, cur = buf; -down_write (&cinode->lock_sem); +cifs_down_write (&cinode->lock_sem); list_for_each_entry_safe(li, tmp, &cfile->llist->locks, llist) { if (flock->fl_start > li->offset || (flock->fl_start + length) <
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 14/75 dccp: do not leak jiffies on the wire
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 3d1e5039f5f87a8731202ceca08764ee7cb010d3 ]
For some reason I missed the case of DCCP passive
flows in my previous patch.
--- net/dccp/ipv4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/dccp/ipv4.c +1 -1
@@ -417,7 +417,7 @@ struct sock *dccp_v4_request_recv_sock(cRCU_INIT_POINTER (newinet->inet_opt,rcu_dereference (ireq->ireq_opt)); newinet->mc_index =inet_iif (skb); newinet->mc_ttl =ip_hdr (skb)->ttl; - newinet->inet_id = jiffies; + newinet->inet_id =prandom_u32 ();if (dst ==NULL && (dst =inet_csk_route_child_sock (sk, newsk, req)) ==NULL ) goto put_and_exit;
Greg Kroah-Hartman
maintainerPATCH 15/75 net: fix sk_page_frag() recursion from memory reclaim
In reply to Greg Kroah-HartmanFrom: Tejun Heo <[email protected]>
[ Upstream commit 20eb4f29b60286e0d6dc01d9c260b4bd383c58fb ]
sk_page_frag() optimizes skb_frag allocations by using per-task skb_frag cache when it knows it's the only user. The condition is determined by seeing whether the socket allocation mask allows blocking - if the allocation may block, it obviously owns the task's context and ergo exclusively owns current->task_frag.
Unfortunately, this misses recursion through memory reclaim path. Please take a look at the following backtrace.
[2] RIP: 0010:tcp_sendmsg_locked+0xccf/0xe10
...
tcp_sendmsg+0x27/0x40
sock_sendmsg+0x30/0x40
sock_xmit.isra.24+0xa1/0x170 [nbd]
nbd_send_cmd+0x1d2/0x690 [nbd]
nbd_queue_rq+0x1b5/0x3b0 [nbd]
__blk_mq_try_issue_directly+0x108/0x1b0
blk_mq_request_issue_directly+0xbd/0xe0
blk_mq_try_issue_list_directly+0x41/0xb0
blk_mq_sched_insert_requests+0xa2/0xe0
blk_mq_flush_plug_list+0x205/0x2a0
blk_flush_plug_list+0xc3/0xf0
[1] blk_finish_plug+0x21/0x2e
_xfs_buf_ioapply+0x313/0x460
__xfs_buf_submit+0x67/0x220
xfs_buf_read_map+0x113/0x1a0
xfs_trans_read_buf_map+0xbf/0x330
xfs_btree_read_buf_block.constprop.42+0x95/0xd0
xfs_btree_lookup_get_block+0x95/0x170
xfs_btree_lookup+0xcc/0x470
xfs_bmap_del_extent_real+0x254/0x9a0
__xfs_bunmapi+0x45c/0xab0
xfs_bunmapi+0x15/0x30
xfs_itruncate_extents_flags+0xca/0x250
xfs_free_eofblocks+0x181/0x1e0
xfs_fs_destroy_inode+0xa8/0x1b0
destroy_inode+0x38/0x70
dispose_list+0x35/0x50
prune_icache_sb+0x52/0x70
super_cache_scan+0x120/0x1a0
do_shrink_slab+0x120/0x290
shrink_slab+0x216/0x2b0
shrink_node+0x1b6/0x4a0
do_try_to_free_pages+0xc6/0x370
try_to_free_mem_cgroup_pages+0xe3/0x1e0
try_charge+0x29e/0x790
mem_cgroup_charge_skmem+0x6a/0x100
__sk_mem_raise_allocated+0x18e/0x390
__sk_mem_schedule+0x2a/0x40
[0] tcp_sendmsg_locked+0x8eb/0xe10
tcp_sendmsg+0x27/0x40
sock_sendmsg+0x30/0x40
___sys_sendmsg+0x26d/0x2b0
__sys_sendmsg+0x57/0xa0
do_syscall_64+0x42/0x100
entry_SYSCALL_64_after_hwframe+0x44/0xa9In [0], tcp_send_msg_locked() was using current->page_frag when it called sk_wmem_schedule(). It already calculated how many bytes can be fit into current->page_frag. Due to memory pressure, sk_wmem_schedule() called into memory reclaim path which called into xfs and then IO issue path. Because the filesystem in question is backed by nbd, the control goes back into the tcp layer - back into tcp_sendmsg_locked().
nbd sets sk_allocation to (GFP_NOIO | __GFP_MEMALLOC) which makes sense - it's in the process of freeing memory and wants to be able to, e.g., drop clean pages to make forward progress. However, this confused sk_page_frag() called from [2]. Because it only tests whether the allocation allows blocking which it does, it now thinks current->page_frag can be used again although it already was being used in [0].
After [2] used current->page_frag, the offset would be increased by the used amount. When the control returns to [0], current->page_frag's offset is increased and the previously calculated number of bytes now may overrun the end of allocated memory leading to silent memory corruptions.
Fix it by adding gfpflags_normal_context() which tests sleepable && !reclaim and use it to determine whether to use current->task_frag.
v2: Eric didn't like gfp flags being tested twice. Introduce a new
helper gfpflags_normal_context() and combine the two tests.
--- include/linux/gfp.h | 23 +++++++++++++++++++++++ include/net/sock.h | 11 ++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-)
include/linux/gfp.h +23 -0
@@ -274,6 +274,29 @@ static inline bool gfpflags_allow_blockireturn (bool __force )(gfp_flags & __GFP_DIRECT_RECLAIM); } +/** +* gfpflags_normal_context - is gfp_flags a normal sleepable context? +* @gfp_flags: gfp_flags to test +* +* Test whether @gfp_flags indicates that the allocation is from the +* %current context and allowed to sleep. +* +* An allocation being allowed to block doesn't mean it owns the %current +* context. When direct reclaim path tries to allocate memory, the +* allocation context is nested inside whatever %current was doing at the +* time of the original allocation. The nested allocation may be allowed +* to block but modifying anything %current owns can corrupt the outer +* context's expectations. +* +* %true result from this function indicates that the allocation context +* can sleep and use anything that's associated with %current. +*/ +static inline bool gfpflags_normal_context (const gfp_t gfp_flags) +{ +return (gfp_flags & (__GFP_DIRECT_RECLAIM | __GFP_MEMALLOC)) == + __GFP_DIRECT_RECLAIM; +} +#ifdef CONFIG_HIGHMEM #define OPT_ZONE_HIGHMEM ZONE_HIGHMEM#else
include/net/sock.h +8 -3
@@ -2077,12 +2077,17 @@ struct sk_buff *sk_stream_alloc_skb(stru* sk_page_frag - return an appropriate page_frag * @sk: socket * -* If socket allocation mode allows current thread to sleep, it means its -* safe to use the per task page_frag instead of the per socket one. +* Use the per task page_frag instead of the per socket one for +* optimization when we know that we're in the normal context and owns +* everything that's associated with %current. +* +* gfpflags_allow_blocking() isn't enough here as direct reclaim may nest +* inside other socket operations and end up recursing into sk_page_frag() +* while it's already in use. */ static inline struct page_frag *sk_page_frag (struct sock *sk) { -if (gfpflags_allow_blocking (sk->sk_allocation)) +if (gfpflags_normal_context (sk->sk_allocation))return ¤t->task_frag;return &sk->sk_frag;
Greg Kroah-Hartman
maintainerPATCH 16/75 net: hisilicon: Fix ping latency when deal with high throughput
In reply to Greg Kroah-HartmanFrom: Jiangfeng Xiao <[email protected]>
[ Upstream commit e56bd641ca61beb92b135298d5046905f920b734 ]
This is due to error in over budget processing.
When dealing with high throughput, the used buffers
that exceeds the budget is not cleaned up. In addition, it takes a lot of cycles to clean up the used buffer,
and then the buffer where the valid data is located can take effect.
--- drivers/net/ethernet/hisilicon/hip04_eth.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
drivers/net/ethernet/hisilicon/hip04_eth.c +9 -6
@@ -174,6 +174,7 @@ struct hip04_priv {dma_addr_t rx_phys[RX_DESC_NUM ];unsigned int rx_head;unsigned int rx_buf_size; +unsigned int rx_cnt_remaining;struct device_node *phy_node;struct phy_device *phy;
@@ -487,7 +488,6 @@ static int hip04_rx_poll(struct napi_str struct hip04_priv *priv = container_of(napi, struct hip04_priv, napi);struct net_device *ndev = priv->ndev;struct net_device_stats *stats = &ndev->stats; -unsigned int cnt =hip04_recv_cnt (priv);struct rx_desc *desc;struct sk_buff *skb;unsigned char *buf;
@@ -500,8 +500,8 @@ static int hip04_rx_poll(struct napi_str/* clean up tx descriptors */ tx_remaining =hip04_tx_reclaim (ndev, false); - -while (cnt && !last) { + priv->rx_cnt_remaining +=hip04_recv_cnt (priv); +while (priv->rx_cnt_remaining && !last) { buf = priv->rx_buf[priv->rx_head]; skb =build_skb (buf, priv->rx_buf_size);if (unlikely (!skb))
@@ -544,11 +544,13 @@ static int hip04_rx_poll(struct napi_strhip04_set_recv_desc (priv, phys); priv->rx_head =RX_NEXT (priv->rx_head); -if (rx >= budget) +if (rx >= budget) { + --priv->rx_cnt_remaining; goto done; + } -if (--cnt ==0 ) - cnt =hip04_recv_cnt (priv); +if (--priv->rx_cnt_remaining ==0 ) + priv->rx_cnt_remaining +=hip04_recv_cnt (priv); }if (!(priv->reg_inten &RCV_INT )) {
@@ -633,6 +635,7 @@ static int hip04_mac_open(struct net_devint i; priv->rx_head =0 ; + priv->rx_cnt_remaining =0 ; priv->tx_head =0 ; priv->tx_tail =0 ;hip04_reset_ppe (priv);
Greg Kroah-Hartman
maintainerPATCH 17/75 net: Zeroing the structure ethtool_wolinfo in ethtool_get_wol()
In reply to Greg Kroah-HartmanFrom: zhanglin <[email protected]>
[ Upstream commit 5ff223e86f5addbfae26419cbb5d61d98f6fbf7d ]
memset() the structure ethtool_wolinfo that has padded bytes but the padded bytes have not been zeroed out.
--- net/core/ethtool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/core/ethtool.c +3 -1
@@ -941,11 +941,13 @@ static int ethtool_reset(struct net_devistatic int ethtool_get_wol (struct net_device *dev,char __user *useraddr) { -struct ethtool_wolinfo wol = { .cmd =ETHTOOL_GWOL }; +struct ethtool_wolinfo wol;if (!dev->ethtool_ops->get_wol)return -EOPNOTSUPP ; +memset (&wol,0 ,sizeof (struct ethtool_wolinfo )); + wol.cmd =ETHTOOL_GWOL ; dev->ethtool_ops->get_wol (dev, &wol);if (copy_to_user (useraddr, &wol,sizeof (wol)))
Greg Kroah-Hartman
maintainerPATCH 18/75 net: add READ_ONCE() annotation in __skb_wait_for_more_packets()
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 7c422d0ce97552dde4a97e6290de70ec6efb0fc6 ]
__skb_wait_for_more_packets() can be called while other cpus can feed packets to the socket receive queue.
KCSAN reported :
BUG: KCSAN: data-race in __skb_wait_for_more_packets / __udp_enqueue_schedule_skb
write to 0xffff888102e40b58 of 8 bytes by interrupt on cpu 0:
__skb_insert include/linux/skbuff.h:1852 [inline] __skb_queue_before include/linux/skbuff.h:1958 [inline] __skb_queue_tail include/linux/skbuff.h:1991 [inline] __udp_enqueue_schedule_skb+0x2d7/0x410 net/ipv4/udp.c:1470 __udp_queue_rcv_skb net/ipv4/udp.c:1940 [inline] udp_queue_rcv_one_skb+0x7bd/0xc70 net/ipv4/udp.c:2057 udp_queue_rcv_skb+0xb5/0x400 net/ipv4/udp.c:2074 udp_unicast_rcv_skb.isra.0+0x7e/0x1c0 net/ipv4/udp.c:2233 __udp4_lib_rcv+0xa44/0x17c0 net/ipv4/udp.c:2300 udp_rcv+0x2b/0x40 net/ipv4/udp.c:2470 ip_protocol_deliver_rcu+0x4d/0x420 net/ipv4/ip_input.c:204 ip_local_deliver_finish+0x110/0x140 net/ipv4/ip_input.c:231 NF_HOOK include/linux/netfilter.h:305 [inline] NF_HOOK include/linux/netfilter.h:299 [inline] ip_local_deliver+0x133/0x210 net/ipv4/ip_input.c:252 dst_input include/net/dst.h:442 [inline] ip_rcv_finish+0x121/0x160 net/ipv4/ip_input.c:413 NF_HOOK include/linux/netfilter.h:305 [inline] NF_HOOK include/linux/netfilter.h:299 [inline] ip_rcv+0x18f/0x1a0 net/ipv4/ip_input.c:523 __netif_receive_skb_one_core+0xa7/0xe0 net/core/dev.c:5010 __netif_receive_skb+0x37/0xf0 net/core/dev.c:5124 process_backlog+0x1d3/0x420 net/core/dev.c:5955
read to 0xffff888102e40b58 of 8 bytes by task 13035 on cpu 1:
__skb_wait_for_more_packets+0xfa/0x320 net/core/datagram.c:100 __skb_recv_udp+0x374/0x500 net/ipv4/udp.c:1683 udp_recvmsg+0xe1/0xb10 net/ipv4/udp.c:1712 inet_recvmsg+0xbb/0x250 net/ipv4/af_inet.c:838 sock_recvmsg_nosec+0x5c/0x70 net/socket.c:871 ___sys_recvmsg+0x1a0/0x3e0 net/socket.c:2480 do_recvmmsg+0x19a/0x5c0 net/socket.c:2601 __sys_recvmmsg+0x1ef/0x200 net/socket.c:2680 __do_sys_recvmmsg net/socket.c:2703 [inline] __se_sys_recvmmsg net/socket.c:2696 [inline] __x64_sys_recvmmsg+0x89/0xb0 net/socket.c:2696 do_syscall_64+0xcc/0x370 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x44/0xa9
Reported by Kernel Concurrency Sanitizer on:
CPU: 1 PID: 13035 Comm: syz-executor.3 Not tainted 5.4.0-rc3+ #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
--- net/core/datagram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/core/datagram.c +1 -1
@@ -96,7 +96,7 @@ static int wait_for_more_packets(structif (error) goto out_err; -if (sk->sk_receive_queue.prev != skb) +if (READ_ONCE (sk->sk_receive_queue.prev) != skb) goto out;/* Socket shut down? */
Greg Kroah-Hartman
maintainerPATCH 19/75 vxlan: check tun_info options_len properly
In reply to Greg Kroah-HartmanFrom: Xin Long <[email protected]>
[ Upstream commit eadf52cf1852196a1363044dcda22fa5d7f296f7 ]
This patch is to improve the tun_info options_len by dropping the skb when TUNNEL_VXLAN_OPT is set but options_len is less than vxlan_metadata. This can void a potential out-of-bounds access on ip_tun_info.
--- drivers/net/vxlan.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/vxlan.c +4 -1
@@ -2006,8 +2006,11 @@ static void vxlan_xmit_one(struct sk_buf ttl = info->key.ttl; tos = info->key.tos; -if (info->options_len) +if (info->options_len) { +if (info->options_len <sizeof (*md)) + goto drop; md =ip_tunnel_info_opts (info); + } }else { md->gbp = skb->mark; }
Greg Kroah-Hartman
maintainerPATCH 20/75 net/mlx4_core: Dynamically set guaranteed amount of counters per VF
In reply to Greg Kroah-HartmanFrom: Eran Ben Elisha <[email protected]>
[ Upstream commit e19868efea0c103f23b4b7e986fd0a703822111f ]
Prior to this patch, the amount of counters guaranteed per VF in the resource tracker was MLX4_VF_COUNTERS_PER_PORT * MLX4_MAX_PORTS. It was set regardless if the VF was single or dual port.
This caused several VFs to have no guaranteed counters although the system could satisfy their request.
The fix is to dynamically guarantee counters, based on each VF specification.
--- drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 42 +++++++++++------- 1 file changed, 26 insertions(+), 16 deletions(-)
drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +26 -16
@@ -463,12 +463,31 @@ void mlx4_init_quotas(struct mlx4_dev *d priv->mfunc.master.res_tracker.res_alloc[RES_MPT ].quota[pf]; } -static int get_max_gauranteed_vfs_counter (struct mlx4_dev *dev) +static int +mlx4_calc_res_counter_guaranteed (struct mlx4_dev *dev, +struct resource_allocator *res_alloc, +int vf) { -/* reduce the sink counter */ -return (dev->caps.max_counters -1 - - (MLX4_PF_COUNTERS_PER_PORT *MLX4_MAX_PORTS )) - /MLX4_MAX_PORTS ; +struct mlx4_active_ports actv_ports; +int ports, counters_guaranteed; + +/* For master, only allocate according to the number of phys ports */ +if (vf ==mlx4_master_func_num (dev)) +return MLX4_PF_COUNTERS_PER_PORT * dev->caps.num_ports; + +/* calculate real number of ports for the VF */ + actv_ports =mlx4_get_active_ports (dev, vf); + ports =bitmap_weight (actv_ports.ports, dev->caps.num_ports); + counters_guaranteed = ports *MLX4_VF_COUNTERS_PER_PORT ; + +/* If we do not have enough counters for this VF, do not +* allocate any for it. '-1' to reduce the sink counter. +*/ +if ((res_alloc->res_reserved + counters_guaranteed) > + (dev->caps.max_counters -1 )) +return 0 ; + +return counters_guaranteed; }int mlx4_init_resource_tracker (struct mlx4_dev *dev)
@@ -476,7 +495,6 @@ int mlx4_init_resource_tracker(struct mlstruct mlx4_priv *priv =mlx4_priv (dev);int i, j;int t; -int max_vfs_guarantee_counter =get_max_gauranteed_vfs_counter (dev); priv->mfunc.master.res_tracker.slave_list = kzalloc(dev->num_slaves * sizeof(struct slave_list),
@@ -593,16 +611,8 @@ int mlx4_init_resource_tracker(struct mlbreak ;case RES_COUNTER : res_alloc->quota[t] = dev->caps.max_counters; -if (t ==mlx4_master_func_num (dev)) - res_alloc->guaranteed[t] = -MLX4_PF_COUNTERS_PER_PORT * -MLX4_MAX_PORTS ; -else if (t <= max_vfs_guarantee_counter) - res_alloc->guaranteed[t] = -MLX4_VF_COUNTERS_PER_PORT * -MLX4_MAX_PORTS ; -else - res_alloc->guaranteed[t] =0 ; + res_alloc->guaranteed[t] = +mlx4_calc_res_counter_guaranteed (dev, res_alloc, t); res_alloc->res_free -= res_alloc->guaranteed[t];break ;default :
Greg Kroah-Hartman
maintainerPATCH 21/75 inet: stop leaking jiffies on the wire
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit a904a0693c189691eeee64f6c6b188bd7dc244e9 ]
Historically linux tried to stick to RFC 791, 1122, 2003 for IPv4 ID field generation.
RFC 6864 made clear that no matter how hard we try, we can not ensure unicity of IP ID within maximum lifetime for all datagrams with a given source address/destination address/protocol tuple.
Linux uses a per socket inet generator (inet_id), initialized at connection startup with a XOR of 'jiffies' and other fields that appear clear on the wire.
Thiemo Nagel pointed that this strategy is a privacy concern as this provides 16 bits of entropy to fingerprint devices.
Let's switch to a random starting point, this is just as good as far as RFC 6864 is concerned and does not leak anything critical.
--- net/dccp/ipv4.c | 2 +- net/ipv4/datagram.c | 2 +- net/ipv4/tcp_ipv4.c | 4 ++-- net/sctp/socket.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-)
net/dccp/ipv4.c +1 -1
@@ -121,7 +121,7 @@ int dccp_v4_connect(struct sock *sk, str inet->inet_daddr, inet->inet_sport, inet->inet_dport); - inet->inet_id = dp->dccps_iss ^ jiffies; + inet->inet_id =prandom_u32 (); err =dccp_connect (sk); rt =NULL ;
net/ipv4/datagram.c +1 -1
@@ -75,7 +75,7 @@ int __ip4_datagram_connect(struct sock * inet->inet_dport = usin->sin_port; sk->sk_state =TCP_ESTABLISHED ;sk_set_txhash (sk); - inet->inet_id = jiffies; + inet->inet_id =prandom_u32 ();sk_dst_set (sk, &rt->dst); err =0 ;
net/ipv4/tcp_ipv4.c +2 -2
@@ -241,7 +241,7 @@ int tcp_v4_connect(struct sock *sk, stru inet->inet_sport, usin->sin_port); - inet->inet_id = tp->write_seq ^ jiffies; + inet->inet_id =prandom_u32 (); err =tcp_connect (sk);
@@ -1302,7 +1302,7 @@ struct sock *tcp_v4_syn_recv_sock(constinet_csk (newsk)->icsk_ext_hdr_len =0 ;if (inet_opt)inet_csk (newsk)->icsk_ext_hdr_len = inet_opt->opt.optlen; - newinet->inet_id = newtp->write_seq ^ jiffies; + newinet->inet_id =prandom_u32 ();if (!dst) { dst =inet_csk_route_child_sock (sk, newsk, req);
net/sctp/socket.c +1 -1
@@ -7267,7 +7267,7 @@ void sctp_copy_sock(struct sock *newsk, newinet->inet_rcv_saddr = inet->inet_rcv_saddr; newinet->inet_dport =htons (asoc->peer.port); newinet->pmtudisc = inet->pmtudisc; - newinet->inet_id = asoc->next_tsn ^ jiffies; + newinet->inet_id =prandom_u32 (); newinet->uc_ttl = inet->uc_ttl; newinet->mc_loop =1 ;
Greg Kroah-Hartman
maintainerPATCH 22/75 net/flow_dissector: switch to siphash
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
commit 55667441c84fa5e0911a0aac44fb059c15ba6da2 upstream.
UDP IPv6 packets auto flowlabels are using a 32bit secret (static u32 hashrnd in net/core/flow_dissector.c) and apply jhash() over fields known by the receivers.
Attackers can easily infer the 32bit secret and use this information to identify a device and/or user, since this 32bit secret is only set at boot time.
Really, using jhash() to generate cookies sent on the wire is a serious security concern.
Trying to change the rol32(hash, 16) in ip6_make_flowlabel() would be a dead end. Trying to periodically change the secret (like in sch_sfq.c) could change paths taken in the network for long lived flows.
Let's switch to siphash, as we did in commit df453700e8d8 ("inet: switch IP ID generator to siphash")
Using a cryptographically strong pseudo random function will solve this privacy issue and more generally remove other weak points in the stack.
Packet schedulers using skb_get_hash_perturb() benefit from this change.
--- include/linux/skbuff.h | 3 +- include/net/flow_dissector.h | 3 +- net/core/flow_dissector.c | 48 +++++++++++++++++-------------------------- net/sched/sch_fq_codel.c | 6 ++--- net/sched/sch_hhf.c | 8 +++---- net/sched/sch_sfb.c | 13 ++++++----- net/sched/sch_sfq.c | 14 +++++++----- 7 files changed, 46 insertions(+), 49 deletions(-)
include/linux/skbuff.h +2 -1
@@ -1073,7 +1073,8 @@ static inline __u32 skb_get_hash_flowi4(return skb->hash; } -__u32 skb_get_hash_perturb (const struct sk_buff *skb,u32 perturb); +__u32 skb_get_hash_perturb (const struct sk_buff *skb, +const siphash_key_t *perturb);static inline __u32 skb_get_hash_raw (const struct sk_buff *skb) {
include/net/flow_dissector.h +2 -1
@@ -3,6 +3,7 @@#include <linux/types.h> #include <linux/in6.h> +#include <linux/siphash.h> #include <uapi/linux/if_ether.h> /**
@@ -146,7 +147,7 @@ struct flow_dissector {struct flow_keys {struct flow_dissector_key_control control;#define FLOW_KEYS_HASH_START_FIELD basic -struct flow_dissector_key_basic basic; +struct flow_dissector_key_basic basic__aligned(SIPHASH_ALIGNMENT) ;struct flow_dissector_key_tags tags;struct flow_dissector_key_keyid keyid;struct flow_dissector_key_ports ports;
net/core/flow_dissector.c +20 -28
110 lines not on this page · raw message
net/sched/sch_fq_codel.c +3 -3
@@ -55,7 +55,7 @@ struct fq_codel_sched_data {struct fq_codel_flow *flows;/* Flows table [flows_cnt] */ u32 *backlogs;/* backlog table [flows_cnt] */ u32 flows_cnt;/* number of flows */ -u32 perturbation;/* hash perturbation */ +siphash_key_t perturbation;/* hash perturbation */ u32 quantum;/* psched_mtu(qdisc_dev(sch)); */ struct codel_params cparams;struct codel_stats cstats;
@@ -69,7 +69,7 @@ struct fq_codel_sched_data {static unsigned int fq_codel_hash (const struct fq_codel_sched_data *q,struct sk_buff *skb) { -u32 hash =skb_get_hash_perturb (skb, q->perturbation); +u32 hash =skb_get_hash_perturb (skb, &q->perturbation);return reciprocal_scale (hash, q->flows_cnt); }
@@ -420,7 +420,7 @@ static int fq_codel_init(struct Qdisc *s sch->limit =10 *1024 ; q->flows_cnt =1024 ; q->quantum =psched_mtu (qdisc_dev (sch)); - q->perturbation =prandom_u32 (); +get_random_bytes (&q->perturbation,sizeof (q->perturbation));INIT_LIST_HEAD (&q->new_flows);INIT_LIST_HEAD (&q->old_flows);codel_params_init (&q->cparams, sch);
net/sched/sch_hhf.c +4 -4
@@ -4,11 +4,11 @@* Copyright (C) 2013 Nandita Dukkipati <[email protected]> */ -#include <linux/jhash.h> #include <linux/jiffies.h> #include <linux/module.h> #include <linux/skbuff.h> #include <linux/vmalloc.h> +#include <linux/siphash.h> #include <net/pkt_sched.h> #include <net/sock.h>
@@ -125,7 +125,7 @@ struct wdrr_bucket {struct hhf_sched_data {struct wdrr_bucket buckets[WDRR_BUCKET_CNT ]; -u32 perturbation;/* hash perturbation */ +siphash_key_t perturbation;/* hash perturbation */ u32 quantum;/* psched_mtu(qdisc_dev(sch)); */ u32 drop_overlimit;/* number of times max qdisc packet * limit was hit
@@ -263,7 +263,7 @@ static enum wdrr_bucket_idx hhf_classify }/* Get hashed flow-id of the skb. */ - hash =skb_get_hash_perturb (skb, q->perturbation); + hash =skb_get_hash_perturb (skb, &q->perturbation);/* Check if this packet belongs to an already established HH flow. */ flow_pos = hash &HHF_BIT_MASK ;
@@ -602,7 +602,7 @@ static int hhf_init(struct Qdisc *sch, s sch->limit =1000 ; q->quantum =psched_mtu (qdisc_dev (sch)); - q->perturbation =prandom_u32 (); +get_random_bytes (&q->perturbation,sizeof (q->perturbation));INIT_LIST_HEAD (&q->new_buckets);INIT_LIST_HEAD (&q->old_buckets);
net/sched/sch_sfb.c +7 -6
@@ -22,7 +22,7 @@#include <linux/errno.h> #include <linux/skbuff.h> #include <linux/random.h> -#include <linux/jhash.h> +#include <linux/siphash.h> #include <net/ip.h> #include <net/pkt_sched.h> #include <net/inet_ecn.h>
@@ -48,7 +48,7 @@ struct sfb_bucket {* (Section 4.4 of SFB reference : moving hash functions) */ struct sfb_bins { -u32 perturbation;/* jhash perturbation */ +siphash_key_t perturbation;/* siphash key */ struct sfb_bucket bins[SFB_LEVELS ][SFB_NUMBUCKETS ]; };
@@ -219,7 +219,8 @@ static u32 sfb_compute_qlen(u32 *prob_r,static void sfb_init_perturbation (u32 slot,struct sfb_sched_data *q) { - q->bins[slot].perturbation =prandom_u32 (); +get_random_bytes (&q->bins[slot].perturbation, +sizeof (q->bins[slot].perturbation)); }static void sfb_swap_slot (struct sfb_sched_data *q)
@@ -313,9 +314,9 @@ static int sfb_enqueue(struct sk_buff *s/* If using external classifiers, get result and record it. */ if (!sfb_classify (skb, fl, &ret, &salt)) goto other_drop; - sfbhash =jhash_1word (salt, q->bins[slot].perturbation); + sfbhash =siphash_1u32 (salt, &q->bins[slot].perturbation); }else { - sfbhash =skb_get_hash_perturb (skb, q->bins[slot].perturbation); + sfbhash =skb_get_hash_perturb (skb, &q->bins[slot].perturbation); }
@@ -351,7 +352,7 @@ static int sfb_enqueue(struct sk_buff *s/* Inelastic flow */ if (q->double_buffering) { sfbhash =skb_get_hash_perturb (skb, - q->bins[slot].perturbation); + &q->bins[slot].perturbation);if (!sfbhash) sfbhash =1 ;sfb_skb_cb (skb)->hashes[slot] = sfbhash;
net/sched/sch_sfq.c +8 -6
@@ -18,7 +18,7 @@#include <linux/errno.h> #include <linux/init.h> #include <linux/skbuff.h> -#include <linux/jhash.h> +#include <linux/siphash.h> #include <linux/slab.h> #include <linux/vmalloc.h> #include <net/netlink.h>
@@ -120,7 +120,7 @@ struct sfq_sched_data {u8 headdrop;u8 maxdepth;/* limit of packets per flow */ -u32 perturbation; +siphash_key_t perturbation;u8 cur_depth;/* depth of longest slot */ u8 flags;unsigned short scaled_quantum;/* SFQ_ALLOT_SIZE(quantum) */
@@ -158,7 +158,7 @@ static inline struct sfq_head *sfq_dep_hstatic unsigned int sfq_hash (const struct sfq_sched_data *q,const struct sk_buff *skb) { -return skb_get_hash_perturb (skb, q->perturbation) & (q->divisor -1 ); +return skb_get_hash_perturb (skb, &q->perturbation) & (q->divisor -1 ); } static unsigned int sfq_classify(struct sk_buff *skb, struct Qdisc *sch,
@@ -607,9 +607,11 @@ static void sfq_perturbation(unsigned lostruct Qdisc *sch = (struct Qdisc *)arg;struct sfq_sched_data *q =qdisc_priv (sch);spinlock_t *root_lock =qdisc_lock (qdisc_root_sleeping (sch)); +siphash_key_t nkey; +get_random_bytes (&nkey,sizeof (nkey));spin_lock (root_lock); - q->perturbation =prandom_u32 (); + q->perturbation = nkey;if (!q->filter_list && q->tail)sfq_rehash (sch);spin_unlock (root_lock);
@@ -681,7 +683,7 @@ static int sfq_change(struct Qdisc *sch,del_timer (&q->perturb_timer);if (q->perturb_period) {mod_timer (&q->perturb_timer, jiffies + q->perturb_period); - q->perturbation =prandom_u32 (); +get_random_bytes (&q->perturbation,sizeof (q->perturbation)); }sch_tree_unlock (sch);kfree (p);
@@ -737,7 +739,7 @@ static int sfq_init(struct Qdisc *sch, s q->quantum =psched_mtu (qdisc_dev (sch)); q->scaled_quantum =SFQ_ALLOT_SIZE (q->quantum); q->perturb_period =0 ; - q->perturbation =prandom_u32 (); +get_random_bytes (&q->perturbation,sizeof (q->perturbation));if (opt) {int err =sfq_change (sch, opt);
Greg Kroah-Hartman
maintainerPATCH 23/75 dmaengine: qcom: bam_dma: Fix resource leak
In reply to Greg Kroah-HartmanFrom: Jeffrey Hugo <[email protected]>
commit 7667819385457b4aeb5fac94f67f52ab52cc10d5 upstream.
bam_dma_terminate_all() will leak resources if any of the transactions are committed to the hardware (present in the desc fifo), and not complete. Since bam_dma_terminate_all() does not cause the hardware to be updated, the hardware will still operate on any previously committed transactions. This can cause memory corruption if the memory for the transaction has been reassigned, and will cause a sync issue between the BAM and its client(s).
Fix this by properly updating the hardware in bam_dma_terminate_all().
--- drivers/dma/qcom_bam_dma.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
drivers/dma/qcom_bam_dma.c +14 -0
@@ -671,7 +671,21 @@ static int bam_dma_terminate_all(struct/* remove all transactions, including active transaction */ spin_lock_irqsave (&bchan->vc.lock, flag); +/* +* If we have transactions queued, then some might be committed to the +* hardware in the desc fifo. The only way to reset the desc fifo is +* to do a hardware reset (either by pipe or the entire block). +* bam_chan_init_hw() will trigger a pipe reset, and also reinit the +* pipe. If the pipe is left disabled (default state after pipe reset) +* and is accessed by a connected hardware engine, a fatal error in +* the BAM will occur. There is a small window where this could happen +* with bam_chan_init_hw(), but it is assumed that the caller has +* stopped activity on any attached hardware engine. Make sure to do +* this first so that the BAM hardware doesn't cause memory corruption +* by accessing freed resources. +*/ if (bchan->curr_txd) { +bam_chan_init_hw (bchan, bchan->curr_txd->dir);list_add (&bchan->curr_txd->vd.node, &bchan->vc.desc_issued); bchan->curr_txd =NULL ; }
Greg Kroah-Hartman
maintainerPATCH 24/75 ARM: 8051/1: put_user: fix possible data corruption in put_user
In reply to Greg Kroah-HartmanFrom: Andrey Ryabinin <[email protected]>
Commit 537094b64b229bf3ad146042f83e74cf6abe59df upstream.
According to arm procedure call standart r2 register is call-cloberred. So after the result of x expression was put into r2 any following function call in p may overwrite r2. To fix this, the result of p expression must be saved to the temporary variable before the assigment x expression to __r2.
--- arch/arm/include/asm/uaccess.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/include/asm/uaccess.h +1 -1
@@ -251,7 +251,7 @@ extern int __put_user_8(void *, unsigned ({ \ unsigned long __limit = current_thread_info()->addr_limit - 1; \ const typeof(*(p)) __user *__tmp_p = (p); \ - register typeof(*(p)) __r2 asm("r2") = (x); \ + register const typeof(*(p)) __r2 asm("r2") = (x); \ register const typeof(*(p)) __user *__p asm("r0") = __tmp_p; \ register unsigned long __l asm("r1") = __limit; \ register int __e asm("r0"); \
Greg Kroah-Hartman
maintainerPATCH 25/75 ARM: 8478/2: arm/arm64: add arm-smccc
In reply to Greg Kroah-HartmanFrom: Jens Wiklander <[email protected]>
Commit 98dd64f34f47ce19b388d9015f767f48393a81eb upstream.
Adds helpers to do SMC and HVC based on ARM SMC Calling Convention. CONFIG_HAVE_ARM_SMCCC is enabled for architectures that may support the SMC or HVC instruction. It's the responsibility of the caller to know if the SMC instruction is supported by the platform.
This patch doesn't provide an implementation of the declared functions. Later patches will bring in implementations and set CONFIG_HAVE_ARM_SMCCC for ARM and ARM64 respectively.
--- drivers/firmware/Kconfig | 3 + include/linux/arm-smccc.h | 104 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+)
drivers/firmware/Kconfig +3 -0
@@ -174,6 +174,9 @@ config QCOM_SCM_64 def_bool y depends on QCOM_SCM && ARM64 +config HAVE_ARM_SMCCC + bool + source "drivers/firmware/broadcom/Kconfig" source "drivers/firmware/google/Kconfig" source "drivers/firmware/efi/Kconfig"
include/linux/arm-smccc.h new file +104 -0
104 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 26/75 ARM: 8479/2: add implementation for arm-smccc
In reply to Greg Kroah-HartmanFrom: Jens Wiklander <[email protected]>
Commit b329f95d70f3f955093e9a2b18ac1ed3587a8f73 upstream.
Adds implementation for arm-smccc and enables CONFIG_HAVE_SMCCC for architectures that may support arm-smccc. It's the responsibility of the caller to know if the SMC instruction is supported by the platform.
--- arch/arm/Kconfig | 1 arch/arm/kernel/Makefile | 2 + arch/arm/kernel/armksyms.c | 6 ++++ arch/arm/kernel/smccc-call.S | 62 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+)
arch/arm/Kconfig +1 -0
@@ -37,6 +37,7 @@ config ARM select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT) select HAVE_ARCH_TRACEHOOK + select HAVE_ARM_SMCCC if CPU_V7 select HAVE_BPF_JIT select HAVE_CC_STACKPROTECTOR select HAVE_CONTEXT_TRACKING
arch/arm/kernel/Makefile +2 -0
@@ -91,4 +91,6 @@ obj-y += psci-call.o obj-$(CONFIG_SMP) += psci_smp.o endif +obj-$(CONFIG_HAVE_ARM_SMCCC) += smccc-call.o + extra-y := $(head-y) vmlinux.lds
arch/arm/kernel/armksyms.c +6 -0
@@ -16,6 +16,7 @@#include <linux/syscalls.h> #include <linux/uaccess.h> #include <linux/io.h> +#include <linux/arm-smccc.h> #include <asm/checksum.h> #include <asm/ftrace.h>
@@ -175,3 +176,8 @@ EXPORT_SYMBOL(__gnu_mcount_nc);EXPORT_SYMBOL (__pv_phys_pfn_offset);EXPORT_SYMBOL (__pv_offset);#endif + +#ifdef CONFIG_HAVE_ARM_SMCCC +EXPORT_SYMBOL (arm_smccc_smc); +EXPORT_SYMBOL (arm_smccc_hvc); +#endif
arch/arm/kernel/smccc-call.S new file +62 -0
62 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 27/75 ARM: 8480/2: arm64: add implementation for arm-smccc
In reply to Greg Kroah-HartmanFrom: Jens Wiklander <[email protected]>
Commit 14457459f9ca2ff8521686168ea179edc3a56a44 upstream.
Adds implementation for arm-smccc and enables CONFIG_HAVE_SMCCC.
--- arch/arm64/Kconfig | 1 arch/arm64/kernel/Makefile | 2 - arch/arm64/kernel/arm64ksyms.c | 5 ++++ arch/arm64/kernel/asm-offsets.c | 3 ++ arch/arm64/kernel/smccc-call.S | 43 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 53 insertions(+), 1 deletion(-)
arch/arm64/Kconfig +1 -0
@@ -92,6 +92,7 @@ config ARM64 select SPARSE_IRQ select SYSCTL_EXCEPTION_TRACE select HAVE_CONTEXT_TRACKING + select HAVE_ARM_SMCCC help ARM 64-bit (AArch64) Linux support.
arch/arm64/kernel/Makefile +1 -1
@@ -17,7 +17,7 @@ arm64-obj-y := debug-monitors.o entry.o hyp-stub.o psci.o psci-call.o cpu_ops.o insn.o \ return_address.o cpuinfo.o cpu_errata.o \ cpufeature.o alternative.o cacheinfo.o \ - smp.o smp_spin_table.o topology.o + smp.o smp_spin_table.o topology.o smccc-call.o extra-$(CONFIG_EFI) := efi-entry.o
arch/arm64/kernel/arm64ksyms.c +5 -0
@@ -26,6 +26,7 @@#include <linux/syscalls.h> #include <linux/uaccess.h> #include <linux/io.h> +#include <linux/arm-smccc.h> #include <asm/checksum.h>
@@ -68,3 +69,7 @@ EXPORT_SYMBOL(test_and_change_bit);#ifdef CONFIG_FUNCTION_TRACER EXPORT_SYMBOL (_mcount);#endif + +/* arm-smccc */ +EXPORT_SYMBOL (arm_smccc_smc); +EXPORT_SYMBOL (arm_smccc_hvc);
arch/arm64/kernel/asm-offsets.c +3 -0
@@ -28,6 +28,7 @@#include <asm/suspend.h> #include <asm/vdso_datapage.h> #include <linux/kbuild.h> +#include <linux/arm-smccc.h> int main (void ) {
@@ -162,5 +163,7 @@ int main(void)DEFINE (SLEEP_SAVE_SP_PHYS , offsetof(struct sleep_save_sp , save_ptr_stash_phys));DEFINE (SLEEP_SAVE_SP_VIRT , offsetof(struct sleep_save_sp , save_ptr_stash));#endif +DEFINE (ARM_SMCCC_RES_X0_OFFS , offsetof(struct arm_smccc_res , a0)); +DEFINE (ARM_SMCCC_RES_X2_OFFS , offsetof(struct arm_smccc_res , a2));return 0 ; }
arch/arm64/kernel/smccc-call.S new file +43 -0
43 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 28/75 ARM: 8481/2: drivers: psci: replace psci firmware calls
In reply to Greg Kroah-HartmanFrom: Jens Wiklander <[email protected]>
Commit e679660dbb8347f275fe5d83a5dd59c1fb6c8e63 upstream.
Switch to use a generic interface for issuing SMC/HVC based on ARM SMC Calling Convention. Removes now the now unused psci-call.S.
--- arch/arm/Kconfig | 2 +- arch/arm/kernel/Makefile | 1 - arch/arm/kernel/psci-call.S | 31 ------------------------------- arch/arm64/kernel/Makefile | 2 +- arch/arm64/kernel/psci-call.S | 28 ---------------------------- drivers/firmware/psci.c | 23 +++++++++++++++++++++-- 6 files changed, 23 insertions(+), 64 deletions(-)
arch/arm/Kconfig +1 -1
@@ -1482,7 +1482,7 @@ config HOTPLUG_CPU config ARM_PSCI bool "Support for the ARM Power State Coordination Interface (PSCI)" - depends on CPU_V7 + depends on HAVE_ARM_SMCCC select ARM_PSCI_FW help Say Y here if you want Linux to communicate with system firmware
arch/arm/kernel/Makefile +0 -1
@@ -87,7 +87,6 @@ obj-$(CONFIG_EARLY_PRINTK) += early_prin obj-$(CONFIG_ARM_VIRT_EXT) += hyp-stub.o ifeq ($(CONFIG_ARM_PSCI),y) -obj-y += psci-call.o obj-$(CONFIG_SMP) += psci_smp.o endif
arch/arm/kernel/psci-call.S deleted +0 -31
@@ -1,31 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Copyright (C) 2015 ARM Limited - * - * Author: Mark Rutland <[email protected]> - */ - -#include <linux/linkage.h> - -#include <asm/opcodes-sec.h> -#include <asm/opcodes-virt.h> - -/* int __invoke_psci_fn_hvc(u32 function_id, u32 arg0, u32 arg1, u32 arg2) */ -ENTRY(__invoke_psci_fn_hvc) - __HVC(0) - bx lr -ENDPROC(__invoke_psci_fn_hvc) - -/* int __invoke_psci_fn_smc(u32 function_id, u32 arg0, u32 arg1, u32 arg2) */ -ENTRY(__invoke_psci_fn_smc) - __SMC(0) - bx lr -ENDPROC(__invoke_psci_fn_smc)
arch/arm64/kernel/Makefile +1 -1
@@ -14,7 +14,7 @@ CFLAGS_REMOVE_return_address.o = -pg arm64-obj-y := debug-monitors.o entry.o irq.o fpsimd.o \ entry-fpsimd.o process.o ptrace.o setup.o signal.o \ sys.o stacktrace.o time.o traps.o io.o vdso.o \ - hyp-stub.o psci.o psci-call.o cpu_ops.o insn.o \ + hyp-stub.o psci.o cpu_ops.o insn.o \ return_address.o cpuinfo.o cpu_errata.o \ cpufeature.o alternative.o cacheinfo.o \ smp.o smp_spin_table.o topology.o smccc-call.o
arch/arm64/kernel/psci-call.S deleted +0 -28
@@ -1,28 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Copyright (C) 2015 ARM Limited - * - * Author: Will Deacon <[email protected]> - */ - -#include <linux/linkage.h> - -/* int __invoke_psci_fn_hvc(u64 function_id, u64 arg0, u64 arg1, u64 arg2) */ -ENTRY(__invoke_psci_fn_hvc) - hvc #0 - ret -ENDPROC(__invoke_psci_fn_hvc) - -/* int __invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1, u64 arg2) */ -ENTRY(__invoke_psci_fn_smc) - smc #0 - ret -ENDPROC(__invoke_psci_fn_smc)
drivers/firmware/psci.c +21 -2
@@ -13,6 +13,7 @@#define pr_fmt (fmt) "psci: " fmt +#include <linux/arm-smccc.h> #include <linux/errno.h> #include <linux/linkage.h> #include <linux/of.h>
@@ -58,8 +59,6 @@ struct psci_operations psci_ops;typedef unsigned long (psci_fn )(unsigned long ,unsigned long ,unsigned long ,unsigned long ); -asmlinkage psci_fn __invoke_psci_fn_hvc; -asmlinkage psci_fn __invoke_psci_fn_smc;static psci_fn *invoke_psci_fn;enum psci_function {
@@ -107,6 +106,26 @@ bool psci_power_state_is_valid(u32 statereturn !(state & ~valid_mask); } +static unsigned long __invoke_psci_fn_hvc (unsigned long function_id, +unsigned long arg0,unsigned long arg1, +unsigned long arg2) +{ +struct arm_smccc_res res; + +arm_smccc_hvc (function_id, arg0, arg1, arg2,0 ,0 ,0 ,0 , &res); +return res.a0; +} + +static unsigned long __invoke_psci_fn_smc (unsigned long function_id, +unsigned long arg0,unsigned long arg1, +unsigned long arg2) +{ +struct arm_smccc_res res; + +arm_smccc_smc (function_id, arg0, arg1, arg2,0 ,0 ,0 ,0 , &res); +return res.a0; +} +static int psci_to_linux_errno (int errno) {switch (errno) {
Greg Kroah-Hartman
maintainerPATCH 29/75 ARM: uaccess: remove put_user() code duplication
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
Commit 9f73bd8bb445e0cbe4bcef6d4cfc788f1e184007 upstream.
Remove the code duplication between put_user() and __put_user(). The code which selected the implementation based upon the pointer size, and declared the local variable to hold the value to be put are common to both implementations.
--- arch/arm/include/asm/uaccess.h | 106 ++++++++++++++++++----------------------- 1 file changed, 49 insertions(+), 57 deletions(-)
arch/arm/include/asm/uaccess.h +49 -57
@@ -238,49 +238,23 @@ extern int __put_user_2(void *, unsignedextern int __put_user_4 (void *,unsigned int );extern int __put_user_8 (void *,unsigned long long ); -#define __put_user_x (__r2, __p, __e, __l, __s) \ - __asm__ __volatile__ ( \ - __asmeq("%0", "r0") __asmeq("%2", "r2") \ - __asmeq("%3", "r1") \ - "bl __put_user_" #__s \ - : "=&r" (__e) \ - : "0" (__p), "r" (__r2), "r" (__l) \ - : "ip", "lr", "cc") - -#define __put_user_check (x, p) \ +#define __put_user_check (__pu_val, __ptr, __err, __s) \ ({ \ unsigned long __limit = current_thread_info()->addr_limit - 1; \ - const typeof(*(p)) __user *__tmp_p = (p); \ - register const typeof(*(p)) __r2 asm("r2") = (x); \ - register const typeof(*(p)) __user *__p asm("r0") = __tmp_p; \ + register typeof(__pu_val) __r2 asm("r2") = __pu_val; \ + register const void __user *__p asm("r0") = __ptr; \ register unsigned long __l asm("r1") = __limit; \ register int __e asm("r0"); \ - unsigned int __ua_flags = uaccess_save_and_enable(); \ - switch (sizeof(*(__p))) { \ - case 1: \ - __put_user_x(__r2, __p, __e, __l, 1); \ - break; \ - case 2: \ - __put_user_x(__r2, __p, __e, __l, 2); \ - break; \ - case 4: \ - __put_user_x(__r2, __p, __e, __l, 4); \ - break; \ - case 8: \ - __put_user_x(__r2, __p, __e, __l, 8); \ - break; \ - default: __e = __put_user_bad(); break; \ - } \ - uaccess_restore(__ua_flags); \ - __e; \ + __asm__ __volatile__ ( \ + __asmeq("%0", "r0") __asmeq("%2", "r2") \ + __asmeq("%3", "r1") \ + "bl __put_user_" #__s \ + : "=&r" (__e) \ + : "0" (__p), "r" (__r2), "r" (__l) \ + : "ip", "lr", "cc"); \ + __err = __e; \ }) -#define put_user (x, p) \ - ({ \ - might_fault(); \ - __put_user_check(x, p); \ - }) -#else /* CONFIG_MMU */ /*
@@ -298,7 +272,7 @@ static inline void set_fs(mm_segment_t f }#define get_user (x, p) __get_user(x, p) -#define put_user (x, p) __put_user(x, p) +#define __put_user_check __put_user_nocheck#endif /* CONFIG_MMU */
@@ -389,36 +363,54 @@ do { \#define __get_user_asm_word (x, addr, err) \ __get_user_asm(x, addr, err, ldr) + +#define __put_user_switch (x, ptr, __err, __fn) \ + do { \ + const __typeof__(*(ptr)) __user *__pu_ptr = (ptr); \ + __typeof__(*(ptr)) __pu_val = (x); \ + unsigned int __ua_flags; \ + might_fault(); \ + __ua_flags = uaccess_save_and_enable(); \ + switch (sizeof(*(ptr))) { \ + case 1: __fn(__pu_val, __pu_ptr, __err, 1); break; \ + case 2: __fn(__pu_val, __pu_ptr, __err, 2); break; \ + case 4: __fn(__pu_val, __pu_ptr, __err, 4); break; \ + case 8: __fn(__pu_val, __pu_ptr, __err, 8); break; \ + default: __err = __put_user_bad(); break; \ + } \ + uaccess_restore(__ua_flags); \ + } while (0) + +#define put_user (x, ptr) \ +({ \ + int __pu_err = 0; \ + __put_user_switch((x), (ptr), __pu_err, __put_user_check); \ + __pu_err; \ +}) +#define __put_user (x, ptr) \ ({ \ long __pu_err = 0; \ - __put_user_err((x), (ptr), __pu_err); \ + __put_user_switch((x), (ptr), __pu_err, __put_user_nocheck); \ __pu_err; \ })#define __put_user_error (x, ptr, err) \ ({ \ - __put_user_err((x), (ptr), err); \ + __put_user_switch((x), (ptr), (err), __put_user_nocheck); \ (void) 0; \ }) -#define __put_user_err (x, ptr, err) \ -do { \ - unsigned long __pu_addr = (unsigned long)(ptr); \ - unsigned int __ua_flags; \ - __typeof__(*(ptr)) __pu_val = (x); \ - __chk_user_ptr(ptr); \ - might_fault(); \ - __ua_flags = uaccess_save_and_enable(); \ - switch (sizeof(*(ptr))) { \ - case 1: __put_user_asm_byte(__pu_val, __pu_addr, err); break; \ - case 2: __put_user_asm_half(__pu_val, __pu_addr, err); break; \ - case 4: __put_user_asm_word(__pu_val, __pu_addr, err); break; \ - case 8: __put_user_asm_dword(__pu_val, __pu_addr, err); break; \ - default: __put_user_bad(); \ - } \ - uaccess_restore(__ua_flags); \ -} while (0) +#define __put_user_nocheck (x, __pu_ptr, __err, __size) \ + do { \ + unsigned long __pu_addr = (unsigned long)__pu_ptr; \ + __put_user_nocheck_##__size(x, __pu_addr, __err); \ + } while (0) + +#define __put_user_nocheck_1 __put_user_asm_byte +#define __put_user_nocheck_2 __put_user_asm_half +#define __put_user_nocheck_4 __put_user_asm_word +#define __put_user_nocheck_8 __put_user_asm_dword#define __put_user_asm (x, __pu_addr, err, instr) \ __asm__ __volatile__( \
Greg Kroah-Hartman
maintainerPATCH 30/75 ARM: Move system register accessors to asm/cp15.h
In reply to Greg Kroah-HartmanFrom: Vladimir Murzin <[email protected]>
Commit 4f2546384150e78cad8045e59a9587fabcd9f9fe upstream.
Headers linux/irqchip/arm-gic.v3.h and arch/arm/include/asm/kvm_hyp.h are included in virt/kvm/arm/hyp/vgic-v3-sr.c and both define macros called __ACCESS_CP15 and __ACCESS_CP15_64 which obviously creates a conflict. These macros were introduced independently for GIC and KVM and, in fact, do the same thing.
As an option we could add prefixes to KVM and GIC version of macros so they won't clash, but it'd introduce code duplication. Alternatively, we could keep macro in, say, GIC header and include it in KVM one (or vice versa), but such dependency would not look nicer.
So we follow arm64 way (it handles this via sysreg.h) and move only single set of macros to asm/cp15.h
--- arch/arm/include/asm/arch_gicv3.h | 27 +++++++++++---------------- arch/arm/include/asm/cp15.h | 15 +++++++++++++++ 2 files changed, 26 insertions(+), 16 deletions(-)
arch/arm/include/asm/arch_gicv3.h +11 -16
@@ -22,9 +22,7 @@#include <linux/io.h> #include <asm/barrier.h> - -#define __ACCESS_CP15 (CRn, Op1, CRm, Op2) p15, Op1, %0, CRn, CRm, Op2 -#define __ACCESS_CP15_64 (Op1, CRm) p15, Op1, %Q0, %R0, CRm +#include <asm/cp15.h> #define ICC_EOIR1 __ACCESS_CP15(c12, 0, c12, 1)#define ICC_DIR __ACCESS_CP15(c12, 0, c11, 1)
@@ -102,58 +100,55 @@static inline void gic_write_eoir (u32 irq) { - asm volatile("mcr " __stringify(ICC_EOIR1) : : "r" (irq)); +write_sysreg (irq,ICC_EOIR1 );isb (); }static inline void gic_write_dir (u32 val) { - asm volatile("mcr " __stringify(ICC_DIR) : : "r" (val)); +write_sysreg (val,ICC_DIR );isb (); }static inline u32 gic_read_iar (void ) { -u32 irqstat; +u32 irqstat =read_sysreg (ICC_IAR1 ); - asm volatile("mrc " __stringify(ICC_IAR1) : "=r" (irqstat));dsb (sy); +return irqstat; }static inline void gic_write_pmr (u32 val) { - asm volatile("mcr " __stringify(ICC_PMR) : : "r" (val)); +write_sysreg (val,ICC_PMR ); }static inline void gic_write_ctlr (u32 val) { - asm volatile("mcr " __stringify(ICC_CTLR) : : "r" (val)); +write_sysreg (val,ICC_CTLR );isb (); }static inline void gic_write_grpen1 (u32 val) { - asm volatile("mcr " __stringify(ICC_IGRPEN1) : : "r" (val)); +write_sysreg (val,ICC_IGRPEN1 );isb (); }static inline void gic_write_sgi1r (u64 val) { - asm volatile("mcrr " __stringify(ICC_SGI1R) : : "r" (val)); +write_sysreg (val,ICC_SGI1R ); }static inline u32 gic_read_sre (void ) { -u32 val; - - asm volatile("mrc " __stringify(ICC_SRE) : "=r" (val)); -return val; +return read_sysreg (ICC_SRE ); }static inline void gic_write_sre (u32 val) { - asm volatile("mcr " __stringify(ICC_SRE) : : "r" (val)); +write_sysreg (val,ICC_SRE );isb (); }
arch/arm/include/asm/cp15.h +15 -0
@@ -49,6 +49,21 @@#ifdef CONFIG_CPU_CP15 +#define __ACCESS_CP15 (CRn, Op1, CRm, Op2) \ + "mrc", "mcr", __stringify(p15, Op1, %0, CRn, CRm, Op2), u32 +#define __ACCESS_CP15_64 (Op1, CRm) \ + "mrrc", "mcrr", __stringify(p15, Op1, %Q0, %R0, CRm), u64 + +#define __read_sysreg (r, w, c, t) ({ \ + t __val; \ + asm volatile(r " " c : "=r" (__val)); \ + __val; \ +}) +#define read_sysreg (...) __read_sysreg(__VA_ARGS__) + +#define __write_sysreg (v, r, w, c, t) asm volatile(w " " c : : "r" ((t)(v))) +#define write_sysreg (v, ...) __write_sysreg(v, __VA_ARGS__) +extern unsigned long cr_alignment;/* defined in entry-armv.S */ static inline unsigned long get_cr (void )
Greg Kroah-Hartman
maintainerPATCH 31/75 arm/arm64: KVM: Advertise SMCCC v1.1
In reply to Greg Kroah-HartmanFrom: Marc Zyngier <[email protected]>
commit 09e6be12effdb33bf7210c8867bbd213b66a499e upstream.
The new SMC Calling Convention (v1.1) allows for a reduced overhead when calling into the firmware, and provides a new feature discovery mechanism.
Make it visible to KVM guests.
--- include/linux/arm-smccc.h | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-)
include/linux/arm-smccc.h +19 -3
@@ -14,9 +14,6 @@#ifndef __LINUX_ARM_SMCCC_H#define __LINUX_ARM_SMCCC_H -#include <linux/linkage.h> -#include <linux/types.h> -/* * This file provides common defines for ARM SMC Calling Convention as * specified in
@@ -60,6 +57,24 @@#define ARM_SMCCC_OWNER_TRUSTED_OS 50#define ARM_SMCCC_OWNER_TRUSTED_OS_END 63 +#define ARM_SMCCC_VERSION_1_0 0x10000 +#define ARM_SMCCC_VERSION_1_1 0x10001 + +#define ARM_SMCCC_VERSION_FUNC_ID \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_32, \ + 0, 0) + +#define ARM_SMCCC_ARCH_FEATURES_FUNC_ID \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_32, \ + 0, 1) + +#ifndef __ASSEMBLY__ + +#include <linux/linkage.h> +#include <linux/types.h> +/** * struct arm_smccc_res - Result from SMC/HVC call * @a0-a3 result values from registers 0 to 3
@@ -101,4 +116,5 @@ asmlinkage void arm_smccc_hvc(unsigned l unsigned long a5, unsigned long a6, unsigned long a7, struct arm_smccc_res *res); +#endif /*__ASSEMBLY__*/ #endif /*__LINUX_ARM_SMCCC_H*/
Greg Kroah-Hartman
maintainerPATCH 32/75 arm64: KVM: Report SMCCC_ARCH_WORKAROUND_1 BP hardening support
In reply to Greg Kroah-HartmanFrom: Marc Zyngier <[email protected]>
commit 6167ec5c9145cdf493722dfd80a5d48bafc4a18a upstream.
A new feature of SMCCC 1.1 is that it offers firmware-based CPU workarounds. In particular, SMCCC_ARCH_WORKAROUND_1 provides BP hardening for CVE-2017-5715.
If the host has some mitigation for this issue, report that we deal with it using SMCCC_ARCH_WORKAROUND_1, as we apply the host workaround on every guest exit.
--- include/linux/arm-smccc.h | 5 +++++ 1 file changed, 5 insertions(+)
include/linux/arm-smccc.h +5 -0
@@ -70,6 +70,11 @@ ARM_SMCCC_SMC_32, \ 0, 1) +#define ARM_SMCCC_ARCH_WORKAROUND_1 \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_32, \ + 0, 0x8000) +#ifndef __ASSEMBLY__#include <linux/linkage.h>
Greg Kroah-Hartman
maintainerPATCH 33/75 firmware/psci: Expose PSCI conduit
In reply to Greg Kroah-HartmanFrom: Marc Zyngier <[email protected]>
commit 09a8d6d48499f93e2abde691f5800081cd858726 upstream.
In order to call into the firmware to apply workarounds, it is useful to find out whether we're using HVC or SMC. Let's expose this through the psci_ops.
--- drivers/firmware/psci.c | 28 +++++++++++++++++++++++----- include/linux/psci.h | 7 +++++++ 2 files changed, 30 insertions(+), 5 deletions(-)
drivers/firmware/psci.c +23 -5
@@ -55,7 +55,9 @@ bool psci_tos_resident_on(int cpu)return cpu == resident_cpu; } -struct psci_operations psci_ops; +struct psci_operations psci_ops = { + .conduit =PSCI_CONDUIT_NONE , +};typedef unsigned long (psci_fn )(unsigned long ,unsigned long ,unsigned long ,unsigned long );
@@ -206,6 +208,22 @@ static unsigned long psci_migrate_info_u 0, 0, 0); } +static void set_conduit (enum psci_conduit conduit) +{ +switch (conduit) { +case PSCI_CONDUIT_HVC : + invoke_psci_fn = __invoke_psci_fn_hvc; +break ; +case PSCI_CONDUIT_SMC : + invoke_psci_fn = __invoke_psci_fn_smc; +break ; +default : +WARN (1 ,"Unexpected PSCI conduit %d\n" , conduit); + } + + psci_ops.conduit = conduit; +} +static int get_set_conduit_method (struct device_node *np) {const char *method;
@@ -218,9 +236,9 @@ static int get_set_conduit_method(struct }if (!strcmp ("hvc" , method)) { - invoke_psci_fn = __invoke_psci_fn_hvc; +set_conduit (PSCI_CONDUIT_HVC ); }else if (!strcmp ("smc" , method)) { - invoke_psci_fn = __invoke_psci_fn_smc; +set_conduit (PSCI_CONDUIT_SMC ); }else {pr_warn ("invalid \"method\" property: %s\n" , method);return -EINVAL ;
@@ -480,9 +498,9 @@ int __init psci_acpi_init(void)pr_info ("probing for conduit method from ACPI.\n" );if (acpi_psci_use_hvc ()) - invoke_psci_fn = __invoke_psci_fn_hvc; +set_conduit (PSCI_CONDUIT_HVC );else - invoke_psci_fn = __invoke_psci_fn_smc; +set_conduit (PSCI_CONDUIT_SMC );return psci_probe (); }
include/linux/psci.h +7 -0
@@ -24,6 +24,12 @@ bool psci_tos_resident_on(int cpu);bool psci_power_state_loses_context (u32 state);bool psci_power_state_is_valid (u32 state); +enum psci_conduit { +PSCI_CONDUIT_NONE , +PSCI_CONDUIT_SMC , +PSCI_CONDUIT_HVC , +}; +struct psci_operations {int (*cpu_suspend)(u32 state,unsigned long entry_point);int (*cpu_off)(u32 state);
@@ -32,6 +38,7 @@ struct psci_operations {int (*affinity_info)(unsigned long target_affinity,unsigned long lowest_affinity_level);int (*migrate_info_type)(void ); +enum psci_conduit conduit; };extern struct psci_operations psci_ops;
Greg Kroah-Hartman
maintainerPATCH 34/75 firmware/psci: Expose SMCCC version through psci_ops
In reply to Greg Kroah-HartmanFrom: Marc Zyngier <[email protected]>
commit e78eef554a912ef6c1e0bbf97619dafbeae3339f upstream.
Since PSCI 1.0 allows the SMCCC version to be (indirectly) probed, let's do that at boot time, and expose the version of the calling convention as part of the psci_ops structure.
--- drivers/firmware/psci.c | 27 +++++++++++++++++++++++++++ include/linux/psci.h | 6 ++++++ 2 files changed, 33 insertions(+)
drivers/firmware/psci.c +27 -0
@@ -57,6 +57,7 @@ bool psci_tos_resident_on(int cpu)struct psci_operations psci_ops = { .conduit =PSCI_CONDUIT_NONE , + .smccc_version =SMCCC_VERSION_1_0 , }; typedef unsigned long (psci_fn)(unsigned long, unsigned long,
@@ -339,6 +340,31 @@ static void __init psci_init_migrate(voipr_info ("Trusted OS resident on physical CPU 0x%lx\n" , cpuid); } +static void __init psci_init_smccc (void ) +{ +u32 ver =ARM_SMCCC_VERSION_1_0 ; +int feature; + + feature =psci_features (ARM_SMCCC_VERSION_FUNC_ID ); + +if (feature !=PSCI_RET_NOT_SUPPORTED ) { +u32 ret; + ret =invoke_psci_fn (ARM_SMCCC_VERSION_FUNC_ID ,0 ,0 ,0 ); +if (ret ==ARM_SMCCC_VERSION_1_1 ) { + psci_ops.smccc_version =SMCCC_VERSION_1_1 ; + ver = ret; + } + } + +/* +* Conveniently, the SMCCC and PSCI versions are encoded the +* same way. No, this isn't accidental. +*/ +pr_info ("SMC Calling Convention v%d.%d\n" , +PSCI_VERSION_MAJOR (ver),PSCI_VERSION_MINOR (ver)); + +} +static void __init psci_0_2_set_functions (void ) {pr_info ("Using standard PSCI v0.2 function IDs\n" );
@@ -385,6 +411,7 @@ static int __init psci_probe(void)psci_init_migrate ();if (PSCI_VERSION_MAJOR (ver) >=1 ) { +psci_init_smccc ();psci_init_cpu_suspend ();psci_init_system_suspend (); }
include/linux/psci.h +6 -0
@@ -30,6 +30,11 @@ enum psci_conduit { PSCI_CONDUIT_HVC, }; +enum smccc_version { +SMCCC_VERSION_1_0 , +SMCCC_VERSION_1_1 , +}; +struct psci_operations {int (*cpu_suspend)(u32 state,unsigned long entry_point);int (*cpu_off)(u32 state);
@@ -39,6 +44,7 @@ struct psci_operations { unsigned long lowest_affinity_level);int (*migrate_info_type)(void );enum psci_conduit conduit; +enum smccc_version smccc_version; };extern struct psci_operations psci_ops;
Greg Kroah-Hartman
maintainerPATCH 35/75 arm/arm64: smccc: Make function identifiers an unsigned quantity
In reply to Greg Kroah-HartmanFrom: Marc Zyngier <[email protected]>
commit ded4c39e93f3b72968fdb79baba27f3b83dad34c upstream.
Function identifiers are a 32bit, unsigned quantity. But we never tell so to the compiler, resulting in the following:
4ac: b26187e0 mov x0, #0xffffffff80000001
We thus rely on the firmware narrowing it for us, which is not always a reasonable expectation.
--- include/linux/arm-smccc.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
include/linux/arm-smccc.h +4 -2
@@ -14,14 +14,16 @@#ifndef __LINUX_ARM_SMCCC_H#define __LINUX_ARM_SMCCC_H +#include <uapi/linux/const.h> +/* * This file provides common defines for ARM SMC Calling Convention as * specified in * http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html */ -#define ARM_SMCCC_STD_CALL 0 -#define ARM_SMCCC_FAST_CALL 1 +#define ARM_SMCCC_STD_CALL _AC(0,U) +#define ARM_SMCCC_FAST_CALL _AC(1,U)#define ARM_SMCCC_TYPE_SHIFT 31#define ARM_SMCCC_SMC_32 0
Greg Kroah-Hartman
maintainerPATCH 36/75 arm/arm64: smccc: Implement SMCCC v1.1 inline primitive
In reply to Greg Kroah-HartmanFrom: Marc Zyngier <[email protected]>
commit f2d3b2e8759a5833df6f022e42df2d581e6d843c upstream.
One of the major improvement of SMCCC v1.1 is that it only clobbers the first 4 registers, both on 32 and 64bit. This means that it becomes very easy to provide an inline version of the SMC call primitive, and avoid performing a function call to stash the registers that would otherwise be clobbered by SMCCC v1.0.
--- include/linux/arm-smccc.h | 141 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+)
include/linux/arm-smccc.h +141 -0
@@ -123,5 +123,146 @@ asmlinkage void arm_smccc_hvc(unsigned l unsigned long a5, unsigned long a6, unsigned long a7, struct arm_smccc_res *res); +/* SMCCC v1.1 implementation madness follows */ +#ifdef CONFIG_ARM64 + +#define SMCCC_SMC_INST "smc #0" +#define SMCCC_HVC_INST "hvc #0" + +#elif defined(CONFIG_ARM ) +#include <asm/opcodes-sec.h> +#include <asm/opcodes-virt.h> + +#define SMCCC_SMC_INST __SMC(0) +#define SMCCC_HVC_INST __HVC(0) + +#endif + +#define ___count_args (_0, _1, _2, _3, _4, _5, _6, _7, _8, x, ...) x + +#define __count_args (...) \ + ___count_args(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0) + +#define __constraint_write_0 \ + "+r" (r0), "=&r" (r1), "=&r" (r2), "=&r" (r3) +#define __constraint_write_1 \ + "+r" (r0), "+r" (r1), "=&r" (r2), "=&r" (r3) +#define __constraint_write_2 \ + "+r" (r0), "+r" (r1), "+r" (r2), "=&r" (r3) +#define __constraint_write_3 \ + "+r" (r0), "+r" (r1), "+r" (r2), "+r" (r3) +#define __constraint_write_4 __constraint_write_3 +#define __constraint_write_5 __constraint_write_4 +#define __constraint_write_6 __constraint_write_5 +#define __constraint_write_7 __constraint_write_6 + +#define __constraint_read_0 +#define __constraint_read_1 +#define __constraint_read_2 +#define __constraint_read_3 +#define __constraint_read_4 "r" (r4) +#define __constraint_read_5 __constraint_read_4, "r" (r5) +#define __constraint_read_6 __constraint_read_5, "r" (r6) +#define __constraint_read_7 __constraint_read_6, "r" (r7) + +#define __declare_arg_0 (a0, res) \ + struct arm_smccc_res *___res = res; \ + register u32 r0 asm("r0") = a0; \ + register unsigned long r1 asm("r1"); \ + register unsigned long r2 asm("r2"); \ + register unsigned long r3 asm("r3") + +#define __declare_arg_1 (a0, a1, res) \ + struct arm_smccc_res *___res = res; \ + register u32 r0 asm("r0") = a0; \ + register typeof(a1) r1 asm("r1") = a1; \ + register unsigned long r2 asm("r2"); \ + register unsigned long r3 asm("r3") + +#define __declare_arg_2 (a0, a1, a2, res) \ + struct arm_smccc_res *___res = res; \ + register u32 r0 asm("r0") = a0; \ + register typeof(a1) r1 asm("r1") = a1; \ + register typeof(a2) r2 asm("r2") = a2; \ + register unsigned long r3 asm("r3") + +#define __declare_arg_3 (a0, a1, a2, a3, res) \ + struct arm_smccc_res *___res = res; \ + register u32 r0 asm("r0") = a0; \ + register typeof(a1) r1 asm("r1") = a1; \ + register typeof(a2) r2 asm("r2") = a2; \ + register typeof(a3) r3 asm("r3") = a3 + +#define __declare_arg_4 (a0, a1, a2, a3, a4, res) \ + __declare_arg_3(a0, a1, a2, a3, res); \ + register typeof(a4) r4 asm("r4") = a4 + +#define __declare_arg_5 (a0, a1, a2, a3, a4, a5, res) \ + __declare_arg_4(a0, a1, a2, a3, a4, res); \ + register typeof(a5) r5 asm("r5") = a5 + +#define __declare_arg_6 (a0, a1, a2, a3, a4, a5, a6, res) \ + __declare_arg_5(a0, a1, a2, a3, a4, a5, res); \ + register typeof(a6) r6 asm("r6") = a6 + +#define __declare_arg_7 (a0, a1, a2, a3, a4, a5, a6, a7, res) \ + __declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res); \ + register typeof(a7) r7 asm("r7") = a7 + +#define ___declare_args (count, ...) __declare_arg_ ## count(__VA_ARGS__) +#define __declare_args (count, ...) ___declare_args(count, __VA_ARGS__) + +#define ___constraints (count) \ + : __constraint_write_ ## count \ + : __constraint_read_ ## count \ + : "memory" +#define __constraints (count) ___constraints(count) + +/* +* We have an output list that is not necessarily used, and GCC feels +* entitled to optimise the whole sequence away. "volatile" is what +* makes it stick. +*/ +#define __arm_smccc_1_1 (inst, ...) \ + do { \ + __declare_args(__count_args(__VA_ARGS__), __VA_ARGS__); \ + asm volatile(inst "\n" \ + __constraints(__count_args(__VA_ARGS__))); \ + if (___res) \ + *___res = (typeof(*___res)){r0, r1, r2, r3}; \ + } while (0) + +/* +* arm_smccc_1_1_smc() - make an SMCCC v1.1 compliant SMC call +* +* This is a variadic macro taking one to eight source arguments, and +* an optional return structure. +* +* @a0-a7: arguments passed in registers 0 to 7 +* @res: result values from registers 0 to 3 +* +* This macro is used to make SMC calls following SMC Calling Convention v1.1. +* The content of the supplied param are copied to registers 0 to 7 prior +* to the SMC instruction. The return values are updated with the content +* from register 0 to 3 on return from the SMC instruction if not NULL. +*/ +#define arm_smccc_1_1_smc (...) __arm_smccc_1_1(SMCCC_SMC_INST, __VA_ARGS__) + +/* +* arm_smccc_1_1_hvc() - make an SMCCC v1.1 compliant HVC call +* +* This is a variadic macro taking one to eight source arguments, and +* an optional return structure. +* +* @a0-a7: arguments passed in registers 0 to 7 +* @res: result values from registers 0 to 3 +* +* This macro is used to make HVC calls following SMC Calling Convention v1.1. +* The content of the supplied param are copied to registers 0 to 7 prior +* to the HVC instruction. The return values are updated with the content +* from register 0 to 3 on return from the HVC instruction if not NULL. +*/ +#define arm_smccc_1_1_hvc (...) __arm_smccc_1_1(SMCCC_HVC_INST, __VA_ARGS__) +#endif /*__ASSEMBLY__*/ #endif /*__LINUX_ARM_SMCCC_H*/
Greg Kroah-Hartman
maintainerPATCH 37/75 arm/arm64: smccc: Add SMCCC-specific return codes
In reply to Greg Kroah-HartmanFrom: Marc Zyngier <[email protected]>
commit eff0e9e1078ea7dc1d794dc50e31baef984c46d7 upstream.
We've so far used the PSCI return codes for SMCCC because they were extremely similar. But with the new ARM DEN 0070A specification, "NOT_REQUIRED" (-2) is clashing with PSCI's "PSCI_RET_INVALID_PARAMS".
Let's bite the bullet and add SMCCC specific return codes. Users can be repainted as and when required.
--- include/linux/arm-smccc.h | 5 +++++ 1 file changed, 5 insertions(+)
include/linux/arm-smccc.h +5 -0
@@ -264,5 +264,10 @@ asmlinkage void arm_smccc_hvc(unsigned l*/ #define arm_smccc_1_1_hvc (...) __arm_smccc_1_1(SMCCC_HVC_INST, __VA_ARGS__) +/* Return codes defined in ARM DEN 0070A */ +#define SMCCC_RET_SUCCESS 0 +#define SMCCC_RET_NOT_SUPPORTED -1 +#define SMCCC_RET_NOT_REQUIRED -2 +#endif /*__ASSEMBLY__*/ #endif /*__LINUX_ARM_SMCCC_H*/
Greg Kroah-Hartman
maintainerPATCH 38/75 arm/arm64: smccc-1.1: Make return values unsigned long
In reply to Greg Kroah-HartmanFrom: Marc Zyngier <[email protected]>
[ Upstream commit 1d8f574708a3fb6f18c85486d0c5217df893c0cf ]
An unfortunate consequence of having a strong typing for the input values to the SMC call is that it also affects the type of the return values, limiting r0 to 32 bits and r{1,2,3} to whatever was passed as an input.
Let's turn everything into "unsigned long", which satisfies the requirements of both architectures, and allows for the full range of return values.
--- include/linux/arm-smccc.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
include/linux/arm-smccc.h +10 -10
@@ -167,31 +167,31 @@ asmlinkage void arm_smccc_hvc(unsigned l#define __declare_arg_0 (a0, res) \ struct arm_smccc_res *___res = res; \ - register u32 r0 asm("r0") = a0; \ + register unsigned long r0 asm("r0") = (u32)a0; \ register unsigned long r1 asm("r1"); \ register unsigned long r2 asm("r2"); \ register unsigned long r3 asm("r3")#define __declare_arg_1 (a0, a1, res) \ struct arm_smccc_res *___res = res; \ - register u32 r0 asm("r0") = a0; \ - register typeof(a1) r1 asm("r1") = a1; \ + register unsigned long r0 asm("r0") = (u32)a0; \ + register unsigned long r1 asm("r1") = a1; \ register unsigned long r2 asm("r2"); \ register unsigned long r3 asm("r3")#define __declare_arg_2 (a0, a1, a2, res) \ struct arm_smccc_res *___res = res; \ - register u32 r0 asm("r0") = a0; \ - register typeof(a1) r1 asm("r1") = a1; \ - register typeof(a2) r2 asm("r2") = a2; \ + register unsigned long r0 asm("r0") = (u32)a0; \ + register unsigned long r1 asm("r1") = a1; \ + register unsigned long r2 asm("r2") = a2; \ register unsigned long r3 asm("r3")#define __declare_arg_3 (a0, a1, a2, a3, res) \ struct arm_smccc_res *___res = res; \ - register u32 r0 asm("r0") = a0; \ - register typeof(a1) r1 asm("r1") = a1; \ - register typeof(a2) r2 asm("r2") = a2; \ - register typeof(a3) r3 asm("r3") = a3 + register unsigned long r0 asm("r0") = (u32)a0; \ + register unsigned long r1 asm("r1") = a1; \ + register unsigned long r2 asm("r2") = a2; \ + register unsigned long r3 asm("r3") = a3#define __declare_arg_4 (a0, a1, a2, a3, a4, res) \ __declare_arg_3(a0, a1, a2, a3, res); \
Greg Kroah-Hartman
maintainerPATCH 39/75 arm/arm64: smccc-1.1: Handle function result as parameters
In reply to Greg Kroah-HartmanFrom: Marc Zyngier <[email protected]>
[ Upstream commit 755a8bf5579d22eb5636685c516d8dede799e27b ]
If someone has the silly idea to write something along those lines:
extern u64 foo(void);
void bar(struct arm_smccc_res *res)
{
arm_smccc_1_1_smc(0xbad, foo(), res);
}they are in for a surprise, as this gets compiled as:
0000000000000588 <bar>: 588: a9be7bfd stp x29, x30, [sp, #-32]! 58c: 910003fd mov x29, sp 590: f9000bf3 str x19, [sp, #16] 594: aa0003f3 mov x19, x0 598: aa1e03e0 mov x0, x30 59c: 94000000 bl 0 <_mcount> 5a0: 94000000 bl 0 <foo> 5a4: aa0003e1 mov x1, x0 5a8: d4000003 smc #0x0 5ac: b4000073 cbz x19, 5b8 <bar+0x30> 5b0: a9000660 stp x0, x1, [x19] 5b4: a9010e62 stp x2, x3, [x19, #16] 5b8: f9400bf3 ldr x19, [sp, #16] 5bc: a8c27bfd ldp x29, x30, [sp], #32 5c0: d65f03c0 ret 5c4: d503201f nop
The call to foo "overwrites" the x0 register for the return value, and we end up calling the wrong secure service.
A solution is to evaluate all the parameters before assigning anything to specific registers, leading to the expected result:
0000000000000588 <bar>: 588: a9be7bfd stp x29, x30, [sp, #-32]! 58c: 910003fd mov x29, sp 590: f9000bf3 str x19, [sp, #16] 594: aa0003f3 mov x19, x0 598: aa1e03e0 mov x0, x30 59c: 94000000 bl 0 <_mcount> 5a0: 94000000 bl 0 <foo> 5a4: aa0003e1 mov x1, x0 5a8: d28175a0 mov x0, #0xbad 5ac: d4000003 smc #0x0 5b0: b4000073 cbz x19, 5bc <bar+0x34> 5b4: a9000660 stp x0, x1, [x19] 5b8: a9010e62 stp x2, x3, [x19, #16] 5bc: f9400bf3 ldr x19, [sp, #16] 5c0: a8c27bfd ldp x29, x30, [sp], #32 5c4: d65f03c0 ret
--- include/linux/arm-smccc.h | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-)
include/linux/arm-smccc.h +20 -10
@@ -173,41 +173,51 @@ asmlinkage void arm_smccc_hvc(unsigned l register unsigned long r3 asm("r3")#define __declare_arg_1 (a0, a1, res) \ + typeof(a1) __a1 = a1; \ struct arm_smccc_res *___res = res; \ register unsigned long r0 asm("r0") = (u32)a0; \ - register unsigned long r1 asm("r1") = a1; \ + register unsigned long r1 asm("r1") = __a1; \ register unsigned long r2 asm("r2"); \ register unsigned long r3 asm("r3")#define __declare_arg_2 (a0, a1, a2, res) \ + typeof(a1) __a1 = a1; \ + typeof(a2) __a2 = a2; \ struct arm_smccc_res *___res = res; \ register unsigned long r0 asm("r0") = (u32)a0; \ - register unsigned long r1 asm("r1") = a1; \ - register unsigned long r2 asm("r2") = a2; \ + register unsigned long r1 asm("r1") = __a1; \ + register unsigned long r2 asm("r2") = __a2; \ register unsigned long r3 asm("r3")#define __declare_arg_3 (a0, a1, a2, a3, res) \ + typeof(a1) __a1 = a1; \ + typeof(a2) __a2 = a2; \ + typeof(a3) __a3 = a3; \ struct arm_smccc_res *___res = res; \ register unsigned long r0 asm("r0") = (u32)a0; \ - register unsigned long r1 asm("r1") = a1; \ - register unsigned long r2 asm("r2") = a2; \ - register unsigned long r3 asm("r3") = a3 + register unsigned long r1 asm("r1") = __a1; \ + register unsigned long r2 asm("r2") = __a2; \ + register unsigned long r3 asm("r3") = __a3#define __declare_arg_4 (a0, a1, a2, a3, a4, res) \ + typeof(a4) __a4 = a4; \ __declare_arg_3(a0, a1, a2, a3, res); \ - register typeof(a4) r4 asm("r4") = a4 + register unsigned long r4 asm("r4") = __a4#define __declare_arg_5 (a0, a1, a2, a3, a4, a5, res) \ + typeof(a5) __a5 = a5; \ __declare_arg_4(a0, a1, a2, a3, a4, res); \ - register typeof(a5) r5 asm("r5") = a5 + register unsigned long r5 asm("r5") = __a5#define __declare_arg_6 (a0, a1, a2, a3, a4, a5, a6, res) \ + typeof(a6) __a6 = a6; \ __declare_arg_5(a0, a1, a2, a3, a4, a5, res); \ - register typeof(a6) r6 asm("r6") = a6 + register unsigned long r6 asm("r6") = __a6#define __declare_arg_7 (a0, a1, a2, a3, a4, a5, a6, a7, res) \ + typeof(a7) __a7 = a7; \ __declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res); \ - register typeof(a7) r7 asm("r7") = a7 + register unsigned long r7 asm("r7") = __a7#define ___declare_args (count, ...) __declare_arg_ ## count(__VA_ARGS__)#define __declare_args (count, ...) ___declare_args(count, __VA_ARGS__)
Greg Kroah-Hartman
maintainerPATCH 40/75 ARM: add more CPU part numbers for Cortex and Brahma B15 CPUs
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
Commit f5683e76f35b4ec5891031b6a29036efe0a1ff84 upstream.
Add CPU part numbers for Cortex A53, A57, A72, A73, A75 and the Broadcom Brahma B15 CPU.
--- arch/arm/include/asm/cputype.h | 8 ++++++++ 1 file changed, 8 insertions(+)
arch/arm/include/asm/cputype.h +8 -0
@@ -74,8 +74,16 @@#define ARM_CPU_PART_CORTEX_A12 0x4100c0d0#define ARM_CPU_PART_CORTEX_A17 0x4100c0e0#define ARM_CPU_PART_CORTEX_A15 0x4100c0f0 +#define ARM_CPU_PART_CORTEX_A53 0x4100d030 +#define ARM_CPU_PART_CORTEX_A57 0x4100d070 +#define ARM_CPU_PART_CORTEX_A72 0x4100d080 +#define ARM_CPU_PART_CORTEX_A73 0x4100d090 +#define ARM_CPU_PART_CORTEX_A75 0x4100d0a0#define ARM_CPU_PART_MASK 0xff00fff0 +/* Broadcom cores */ +#define ARM_CPU_PART_BRAHMA_B15 0x420000f0 +#define ARM_CPU_XSCALE_ARCH_MASK 0xe000#define ARM_CPU_XSCALE_ARCH_V1 0x2000#define ARM_CPU_XSCALE_ARCH_V2 0x4000
Greg Kroah-Hartman
maintainerPATCH 41/75 ARM: bugs: prepare processor bug infrastructure
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
Commit a5b9177f69329314721aa7022b7e69dab23fa1f0 upstream.
Prepare the processor bug infrastructure so that it can be expanded to check for per-processor bugs.
--- arch/arm/include/asm/bugs.h | 4 ++-- arch/arm/kernel/Makefile | 1 + arch/arm/kernel/bugs.c | 9 +++++++++ 3 files changed, 12 insertions(+), 2 deletions(-)
arch/arm/include/asm/bugs.h +2 -2
@@ -10,10 +10,10 @@#ifndef __ASM_BUGS_H#define __ASM_BUGS_H -#ifdef CONFIG_MMU extern void check_writebuffer_bugs (void ); -#define check_bugs () check_writebuffer_bugs() +#ifdef CONFIG_MMU +extern void check_bugs (void );#else #define check_bugs () do { } while (0)#endif
arch/arm/kernel/Makefile +1 -0
@@ -30,6 +30,7 @@ else obj-y += entry-armv.o endif +obj-$(CONFIG_MMU) += bugs.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o obj-$(CONFIG_ISA_DMA_API) += dma.o obj-$(CONFIG_FIQ) += fiq.o fiqasm.o
arch/arm/kernel/bugs.c new file +9 -0
@@ -0,0 +1,9 @@ +// SPDX-Identifier: GPL-2.0 +#include <linux/init.h> +#include <asm/bugs.h> +#include <asm/proc-fns.h> + +void __init check_bugs (void ) +{ +check_writebuffer_bugs (); +}
Greg Kroah-Hartman
maintainerPATCH 42/75 ARM: bugs: hook processor bug checking into SMP and suspend paths
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
Commit 26602161b5ba795928a5a719fe1d5d9f2ab5c3ef upstream.
Check for CPU bugs when secondary processors are being brought online, and also when CPUs are resuming from a low power mode. This gives an opportunity to check that processor specific bug workarounds are correctly enabled for all paths that a CPU re-enters the kernel.
--- arch/arm/include/asm/bugs.h | 2 ++ arch/arm/kernel/bugs.c | 5 +++++ arch/arm/kernel/smp.c | 4 ++++ arch/arm/kernel/suspend.c | 2 ++ 4 files changed, 13 insertions(+)
arch/arm/include/asm/bugs.h +2 -0
@@ -14,8 +14,10 @@ extern void check_writebuffer_bugs(void)#ifdef CONFIG_MMU extern void check_bugs (void ); +extern void check_other_bugs (void );#else #define check_bugs () do { } while (0) +#define check_other_bugs () do { } while (0)#endif #endif
arch/arm/kernel/bugs.c +5 -0
@@ -3,7 +3,12 @@#include <asm/bugs.h> #include <asm/proc-fns.h> +void check_other_bugs (void ) +{ +} +void __init check_bugs (void ) {check_writebuffer_bugs (); +check_other_bugs (); }
arch/arm/kernel/smp.c +4 -0
@@ -29,6 +29,7 @@#include <linux/irq_work.h> #include <linux/atomic.h> +#include <asm/bugs.h> #include <asm/smp.h> #include <asm/cacheflush.h> #include <asm/cpu.h>
@@ -396,6 +397,9 @@ asmlinkage void secondary_start_kernel(v* before we continue - which happens after __cpu_up returns. */ set_cpu_online (cpu, true); + +check_other_bugs (); +complete (&cpu_running);local_irq_enable ();
arch/arm/kernel/suspend.c +2 -0
@@ -1,6 +1,7 @@#include <linux/init.h> #include <linux/slab.h> +#include <asm/bugs.h> #include <asm/cacheflush.h> #include <asm/idmap.h> #include <asm/pgalloc.h>
@@ -34,6 +35,7 @@ int cpu_suspend(unsigned long arg, int (cpu_switch_mm (mm->pgd, mm);local_flush_bp_all ();local_flush_tlb_all (); +check_other_bugs (); }return ret;
Greg Kroah-Hartman
maintainerPATCH 43/75 ARM: bugs: add support for per-processor bug checking
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
Commit 9d3a04925deeabb97c8e26d940b501a2873e8af3 upstream.
Add support for per-processor bug checking - each processor function descriptor gains a function pointer for this check, which must not be an __init function. If non-NULL, this will be called whenever a CPU enters the kernel via which ever path (boot CPU, secondary CPU startup, CPU resuming, etc.)
This allows processor specific bug checks to validate that workaround bits are properly enabled by firmware via all entry paths to the kernel.
--- arch/arm/include/asm/proc-fns.h | 4 ++++ arch/arm/kernel/bugs.c | 4 ++++ arch/arm/mm/proc-macros.S | 3 ++- 3 files changed, 10 insertions(+), 1 deletion(-)
arch/arm/include/asm/proc-fns.h +4 -0
@@ -37,6 +37,10 @@ extern struct processor {*/ void (*_proc_init)(void );/* +* Check for processor bugs +*/ +void (*check_bugs)(void ); +/* * Disable any processor specifics */ void (*_proc_fin)(void );
arch/arm/kernel/bugs.c +4 -0
@@ -5,6 +5,10 @@void check_other_bugs (void ) { +#ifdef MULTI_CPU +if (processor.check_bugs) + processor.check_bugs (); +#endif }void __init check_bugs (void )
arch/arm/mm/proc-macros.S +2 -1
@@ -258,13 +258,14 @@ mcr p15, 0, ip, c7, c10, 4 @ data write barrier .endm -.macro define_processor_functions name:req, dabort:req, pabort:req, nommu=0, suspend=0 +.macro define_processor_functions name:req, dabort:req, pabort:req, nommu=0, suspend=0, bugs=0 .type \name\()_processor_functions, #object .align 2 ENTRY(\name\()_processor_functions) .word \dabort .word \pabort .word cpu_\name\()_proc_init + .word \bugs .word cpu_\name\()_proc_fin .word cpu_\name\()_reset .word cpu_\name\()_do_idle
Greg Kroah-Hartman
maintainerPATCH 44/75 ARM: spectre: add Kconfig symbol for CPUs vulnerable to Spectre
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
Commit c58d237d0852a57fde9bc2c310972e8f4e3d155d upstream.
Add a Kconfig symbol for CPUs which are vulnerable to the Spectre attacks.
--- arch/arm/mm/Kconfig | 4 ++++ 1 file changed, 4 insertions(+)
arch/arm/mm/Kconfig +4 -0
@@ -396,6 +396,7 @@ config CPU_V7 select CPU_CP15_MPU if !MMU select CPU_HAS_ASID if MMU select CPU_PABRT_V7 + select CPU_SPECTRE if MMU select CPU_TLB_V7 if MMU # ARMv7M
@@ -793,6 +794,9 @@ config CPU_BPREDICT_DISABLE help Say Y here to disable branch prediction. If unsure, say N. +config CPU_SPECTRE + bool + config TLS_REG_EMUL bool select NEED_KUSER_HELPERS
Greg Kroah-Hartman
maintainerPATCH 45/75 ARM: spectre-v2: harden branch predictor on context switches
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
Commit 06c23f5ffe7ad45b908d0fff604dae08a7e334b9 upstream.
Required manual merge of arch/arm/mm/proc-v7.S.
Harden the branch predictor against Spectre v2 attacks on context switches for ARMv7 and later CPUs. We do this by:
Cortex A9, A12, A17, A73, A75: invalidating the BTB. Cortex A15, Brahma B15: invalidating the instruction cache.
Cortex A57 and Cortex A72 are not addressed in this patch.
Cortex R7 and Cortex R8 are also not addressed as we do not enforce memory protection on these cores.
--- arch/arm/mm/Kconfig | 19 ++++++ arch/arm/mm/proc-v7-2level.S | 6 -- arch/arm/mm/proc-v7.S | 125 +++++++++++++++++++++++++++++++++---------- 3 files changed, 115 insertions(+), 35 deletions(-)
arch/arm/mm/Kconfig +19 -0
@@ -797,6 +797,25 @@ config CPU_BPREDICT_DISABLE config CPU_SPECTRE bool +config HARDEN_BRANCH_PREDICTOR + bool "Harden the branch predictor against aliasing attacks" if EXPERT + depends on CPU_SPECTRE + default y + help + Speculation attacks against some high-performance processors rely + on being able to manipulate the branch predictor for a victim + context by executing aliasing branches in the attacker context. + Such attacks can be partially mitigated against by clearing + internal branch predictor state and limiting the prediction + logic in some situations. + + This config option will take CPU-specific actions to harden + the branch predictor against aliasing attacks and may rely on + specific instruction sequences or control bits being set by + the system firmware. + + If unsure, say Y. + config TLS_REG_EMUL bool select NEED_KUSER_HELPERS
arch/arm/mm/proc-v7-2level.S +0 -6
@@ -41,11 +41,6 @@ * even on Cortex-A8 revisions not affected by 430973. * If IBE is not set, the flush BTAC/BTB won't do anything. */ -ENTRY(cpu_ca8_switch_mm) -#ifdef CONFIG_MMU - mov r2, #0 - mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB -#endif ENTRY(cpu_v7_switch_mm) #ifdef CONFIG_MMU mmid r1, r1 @ get mm->context.id
@@ -66,7 +61,6 @@ ENTRY(cpu_v7_switch_mm) #endif bx lr ENDPROC(cpu_v7_switch_mm) -ENDPROC(cpu_ca8_switch_mm) /* * cpu_v7_set_pte_ext(ptep, pte)
arch/arm/mm/proc-v7.S +96 -29
173 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 46/75 ARM: spectre-v2: add Cortex A8 and A15 validation of the IBE bit
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
Commit e388b80288aade31135aca23d32eee93dd106795 upstream.
When the branch predictor hardening is enabled, firmware must have set the IBE bit in the auxiliary control register. If this bit has not been set, the Spectre workarounds will not be functional.
Add validation that this bit is set, and print a warning at alert level if this is not the case.
--- arch/arm/mm/Makefile | 2 +- arch/arm/mm/proc-v7-bugs.c | 36 ++++++++++++++++++++++++++++++++++++ arch/arm/mm/proc-v7.S | 4 ++-- 3 files changed, 39 insertions(+), 3 deletions(-)
arch/arm/mm/Makefile +1 -1
@@ -92,7 +92,7 @@ obj-$(CONFIG_CPU_MOHAWK) += proc-mohawk. obj-$(CONFIG_CPU_FEROCEON) += proc-feroceon.o obj-$(CONFIG_CPU_V6) += proc-v6.o obj-$(CONFIG_CPU_V6K) += proc-v6.o -obj-$(CONFIG_CPU_V7) += proc-v7.o +obj-$(CONFIG_CPU_V7) += proc-v7.o proc-v7-bugs.o obj-$(CONFIG_CPU_V7M) += proc-v7m.o AFLAGS_proc-v6.o :=-Wa,-march=armv6
arch/arm/mm/proc-v7-bugs.c new file +36 -0
@@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <linux/kernel.h> +#include <linux/smp.h> + +static __maybe_unused void cpu_v7_check_auxcr_set (bool *warned, +u32 mask,const char *msg) +{ +u32 aux_cr; + + asm("mrc p15, 0, %0, c1, c0, 1" :"=r" (aux_cr)); + +if ((aux_cr & mask) != mask) { +if (!*warned) +pr_err ("CPU%u: %s" ,smp_processor_id (), msg); + *warned = true; + } +} + +static DEFINE_PER_CPU(bool, spectre_warned); + +static void check_spectre_auxcr (bool *warned,u32 bit) +{ +if (IS_ENABLED (CONFIG_HARDEN_BRANCH_PREDICTOR ) && +cpu_v7_check_auxcr_set (warned, bit, + "Spectre v2: firmware did not set auxiliary control register IBE bit, system vulnerable\n"); +} + +void cpu_v7_ca8_ibe (void ) +{ +check_spectre_auxcr (this_cpu_ptr (&spectre_warned),BIT (6 )); +} + +void cpu_v7_ca15_ibe (void ) +{ +check_spectre_auxcr (this_cpu_ptr (&spectre_warned),BIT (0 )); +}
arch/arm/mm/proc-v7.S +2 -2
@@ -511,7 +511,7 @@ __v7_setup_stack: globl_equ cpu_ca8_do_suspend, cpu_v7_do_suspend globl_equ cpu_ca8_do_resume, cpu_v7_do_resume #endif - define_processor_functions ca8, dabort=v7_early_abort, pabort=v7_pabort, suspend=1 + define_processor_functions ca8, dabort=v7_early_abort, pabort=v7_pabort, suspend=1, bugs=cpu_v7_ca8_ibe @ Cortex-A9 - needs more registers preserved across suspend/resume @ and bpiall switch_mm for hardening
@@ -544,7 +544,7 @@ __v7_setup_stack: globl_equ cpu_ca15_suspend_size, cpu_v7_suspend_size globl_equ cpu_ca15_do_suspend, cpu_v7_do_suspend globl_equ cpu_ca15_do_resume, cpu_v7_do_resume - define_processor_functions ca15, dabort=v7_early_abort, pabort=v7_pabort, suspend=1 + define_processor_functions ca15, dabort=v7_early_abort, pabort=v7_pabort, suspend=1, bugs=cpu_v7_ca15_ibe #ifdef CONFIG_CPU_PJ4B define_processor_functions pj4b, dabort=v7_early_abort, pabort=v7_pabort, suspend=1 #endif
Greg Kroah-Hartman
maintainerPATCH 47/75 ARM: spectre-v2: harden user aborts in kernel space
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
Commit f5fe12b1eaee220ce62ff9afb8b90929c396595f upstream.
In order to prevent aliasing attacks on the branch predictor, invalidate the BTB or instruction cache on CPUs that are known to be affected when taking an abort on a address that is outside of a user task limit:
Cortex A8, A9, A12, A17, A73, A75: flush BTB.
Cortex A15, Brahma B15: invalidate icache.
If the IBE bit is not set, then there is little point to enabling the workaround.
--- arch/arm/include/asm/cp15.h | 3 + arch/arm/include/asm/system_misc.h | 15 +++++++ arch/arm/mm/fault.c | 3 + arch/arm/mm/proc-v7-bugs.c | 73 ++++++++++++++++++++++++++++++++++--- arch/arm/mm/proc-v7.S | 8 ++-- 5 files changed, 94 insertions(+), 8 deletions(-)
arch/arm/include/asm/cp15.h +3 -0
@@ -64,6 +64,9 @@#define __write_sysreg (v, r, w, c, t) asm volatile(w " " c : : "r" ((t)(v)))#define write_sysreg (v, ...) __write_sysreg(v, __VA_ARGS__) +#define BPIALL __ACCESS_CP15(c7, 0, c5, 6) +#define ICIALLU __ACCESS_CP15(c7, 0, c5, 0) +extern unsigned long cr_alignment;/* defined in entry-armv.S */ static inline unsigned long get_cr (void )
arch/arm/include/asm/system_misc.h +15 -0
@@ -7,6 +7,7 @@#include <linux/linkage.h> #include <linux/irqflags.h> #include <linux/reboot.h> +#include <linux/percpu.h> extern void cpu_init (void );
@@ -14,6 +15,20 @@ void soft_restart(unsigned long);extern void (*arm_pm_restart)(enum reboot_mode reboot_mode,const char *cmd);extern void (*arm_pm_idle)(void ); +#ifdef CONFIG_HARDEN_BRANCH_PREDICTOR +typedef void (*harden_branch_predictor_fn_t )(void ); +DECLARE_PER_CPU (harden_branch_predictor_fn_t, harden_branch_predictor_fn); +static inline void harden_branch_predictor (void ) +{ +harden_branch_predictor_fn_t fn =per_cpu (harden_branch_predictor_fn, +smp_processor_id ()); +if (fn) +fn (); +} +#else +#define harden_branch_predictor () do { } while (0) +#endif +#define UDBG_UNDEFINED (1 << 0)#define UDBG_SYSCALL (1 << 1)#define UDBG_BADABORT (1 << 2)
arch/arm/mm/fault.c +3 -0
@@ -163,6 +163,9 @@ __do_user_fault(struct task_struct *tsk, {struct siginfo si; +if (addr >TASK_SIZE ) +harden_branch_predictor (); +#ifdef CONFIG_DEBUG_USER if (((user_debug &UDBG_SEGV ) && (sig ==SIGSEGV )) || ((user_debug &UDBG_BUS ) && (sig ==SIGBUS ))) {
arch/arm/mm/proc-v7-bugs.c +68 -5
99 lines not on this page · raw message
arch/arm/mm/proc-v7.S +5 -3
@@ -474,8 +474,10 @@ __v7_setup_stack: __INITDATA + .weak cpu_v7_bugs_init + @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) - define_processor_functions v7, dabort=v7_early_abort, pabort=v7_pabort, suspend=1 + define_processor_functions v7, dabort=v7_early_abort, pabort=v7_pabort, suspend=1, bugs=cpu_v7_bugs_init #ifdef CONFIG_HARDEN_BRANCH_PREDICTOR @ generic v7 bpiall on context switch
@@ -490,7 +492,7 @@ __v7_setup_stack: globl_equ cpu_v7_bpiall_do_suspend, cpu_v7_do_suspend globl_equ cpu_v7_bpiall_do_resume, cpu_v7_do_resume #endif - define_processor_functions v7_bpiall, dabort=v7_early_abort, pabort=v7_pabort, suspend=1 + define_processor_functions v7_bpiall, dabort=v7_early_abort, pabort=v7_pabort, suspend=1, bugs=cpu_v7_bugs_init #define HARDENED_BPIALL_PROCESSOR_FUNCTIONS v7_bpiall_processor_functions #else
@@ -526,7 +528,7 @@ __v7_setup_stack: globl_equ cpu_ca9mp_switch_mm, cpu_v7_switch_mm #endif globl_equ cpu_ca9mp_set_pte_ext, cpu_v7_set_pte_ext - define_processor_functions ca9mp, dabort=v7_early_abort, pabort=v7_pabort, suspend=1 + define_processor_functions ca9mp, dabort=v7_early_abort, pabort=v7_pabort, suspend=1, bugs=cpu_v7_bugs_init #endif @ Cortex-A15 - needs iciallu switch_mm for hardening
Greg Kroah-Hartman
maintainerPATCH 48/75 ARM: spectre-v2: add firmware based hardening
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
Commit 10115105cb3aa17b5da1cb726ae8dd5f6854bd93 upstream.
Add firmware based hardening for cores that require more complex handling in firmware.
--- arch/arm/mm/proc-v7-bugs.c | 60 +++++++++++++++++++++++++++++++++++++++++++++ arch/arm/mm/proc-v7.S | 21 +++++++++++++++ 2 files changed, 81 insertions(+)
arch/arm/mm/proc-v7-bugs.c +60 -0
@@ -1,14 +1,20 @@// SPDX-License-Identifier: GPL-2.0 +#include <linux/arm-smccc.h> #include <linux/kernel.h> +#include <linux/psci.h> #include <linux/smp.h> #include <asm/cp15.h> #include <asm/cputype.h> +#include <asm/proc-fns.h> #include <asm/system_misc.h> #ifdef CONFIG_HARDEN_BRANCH_PREDICTOR DEFINE_PER_CPU (harden_branch_predictor_fn_t, harden_branch_predictor_fn); +extern void cpu_v7_smc_switch_mm (phys_addr_t pgd_phys,struct mm_struct *mm); +extern void cpu_v7_hvc_switch_mm (phys_addr_t pgd_phys,struct mm_struct *mm); +static void harden_branch_predictor_bpiall (void ) {write_sysreg (0 ,BPIALL );
@@ -19,6 +25,16 @@ static void harden_branch_predictor_iciawrite_sysreg (0 ,ICIALLU ); } +static void __maybe_unused call_smc_arch_workaround_1 (void ) +{ +arm_smccc_1_1_smc (ARM_SMCCC_ARCH_WORKAROUND_1 ,NULL ); +} + +static void __maybe_unused call_hvc_arch_workaround_1 (void ) +{ +arm_smccc_1_1_hvc (ARM_SMCCC_ARCH_WORKAROUND_1 ,NULL ); +} +static void cpu_v7_spectre_init (void ) {const char *spectre_v2_method =NULL ;
@@ -45,7 +61,51 @@ static void cpu_v7_spectre_init(void) harden_branch_predictor_iciallu; spectre_v2_method ="ICIALLU" ;break ; + +#ifdef CONFIG_ARM_PSCI +default : +/* Other ARM CPUs require no workaround */ +if (read_cpuid_implementor () ==ARM_CPU_IMP_ARM ) +break ; +/* fallthrough */ +/* Cortex A57/A72 require firmware workaround */ +case ARM_CPU_PART_CORTEX_A57 : +case ARM_CPU_PART_CORTEX_A72 : { +struct arm_smccc_res res; + +if (psci_ops.smccc_version ==SMCCC_VERSION_1_0 ) +break ; + +switch (psci_ops.conduit) { +case PSCI_CONDUIT_HVC : +arm_smccc_1_1_hvc (ARM_SMCCC_ARCH_FEATURES_FUNC_ID , +ARM_SMCCC_ARCH_WORKAROUND_1 , &res); +if ((int )res.a0 !=0 ) +break ; +per_cpu (harden_branch_predictor_fn, cpu) = + call_hvc_arch_workaround_1; + processor.switch_mm = cpu_v7_hvc_switch_mm; + spectre_v2_method ="hypervisor" ; +break ; + +case PSCI_CONDUIT_SMC : +arm_smccc_1_1_smc (ARM_SMCCC_ARCH_FEATURES_FUNC_ID , +ARM_SMCCC_ARCH_WORKAROUND_1 , &res); +if ((int )res.a0 !=0 ) +break ; +per_cpu (harden_branch_predictor_fn, cpu) = + call_smc_arch_workaround_1; + processor.switch_mm = cpu_v7_smc_switch_mm; + spectre_v2_method ="firmware" ; +break ; + +default : +break ; + } } +#endif + } +if (spectre_v2_method)pr_info ("CPU%u: Spectre v2: using %s workaround\n" ,smp_processor_id (), spectre_v2_method);
arch/arm/mm/proc-v7.S +21 -0
@@ -9,6 +9,7 @@ * * This is the "shell" of the ARMv7 processor support. */ +#include <linux/arm-smccc.h> #include <linux/init.h> #include <linux/linkage.h> #include <asm/assembler.h>
@@ -87,6 +88,26 @@ ENTRY(cpu_v7_dcache_clean_area) ret lr ENDPROC(cpu_v7_dcache_clean_area) +#ifdef CONFIG_ARM_PSCI + .arch_extension sec +ENTRY(cpu_v7_smc_switch_mm) + stmfd sp!, {r0 - r3} + movw r0, #:lower16:ARM_SMCCC_ARCH_WORKAROUND_1 + movt r0, #:upper16:ARM_SMCCC_ARCH_WORKAROUND_1 + smc #0 + ldmfd sp!, {r0 - r3} + b cpu_v7_switch_mm +ENDPROC(cpu_v7_smc_switch_mm) + .arch_extension virt +ENTRY(cpu_v7_hvc_switch_mm) + stmfd sp!, {r0 - r3} + movw r0, #:lower16:ARM_SMCCC_ARCH_WORKAROUND_1 + movt r0, #:upper16:ARM_SMCCC_ARCH_WORKAROUND_1 + hvc #0 + ldmfd sp!, {r0 - r3} + b cpu_v7_switch_mm +ENDPROC(cpu_v7_hvc_switch_mm) +#endif ENTRY(cpu_v7_iciallu_switch_mm) mov r3, #0 mcr p15, 0, r3, c7, c5, 0 @ ICIALLU
Greg Kroah-Hartman
maintainerPATCH 49/75 ARM: spectre-v2: warn about incorrect context switching functions
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
Commit c44f366ea7c85e1be27d08f2f0880f4120698125 upstream.
Warn at error level if the context switching function is not what we are expecting. This can happen with big.Little systems, which we currently do not support.
--- arch/arm/mm/proc-v7-bugs.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
arch/arm/mm/proc-v7-bugs.c +15 -0
@@ -12,6 +12,8 @@#ifdef CONFIG_HARDEN_BRANCH_PREDICTOR DEFINE_PER_CPU (harden_branch_predictor_fn_t, harden_branch_predictor_fn); +extern void cpu_v7_iciallu_switch_mm (phys_addr_t pgd_phys,struct mm_struct *mm); +extern void cpu_v7_bpiall_switch_mm (phys_addr_t pgd_phys,struct mm_struct *mm);extern void cpu_v7_smc_switch_mm (phys_addr_t pgd_phys,struct mm_struct *mm);extern void cpu_v7_hvc_switch_mm (phys_addr_t pgd_phys,struct mm_struct *mm);
@@ -50,6 +52,8 @@ static void cpu_v7_spectre_init(void)case ARM_CPU_PART_CORTEX_A17 :case ARM_CPU_PART_CORTEX_A73 :case ARM_CPU_PART_CORTEX_A75 : +if (processor.switch_mm != cpu_v7_bpiall_switch_mm) + goto bl_error;per_cpu (harden_branch_predictor_fn, cpu) = harden_branch_predictor_bpiall; spectre_v2_method ="BPIALL" ;
@@ -57,6 +61,8 @@ static void cpu_v7_spectre_init(void)case ARM_CPU_PART_CORTEX_A15 :case ARM_CPU_PART_BRAHMA_B15 : +if (processor.switch_mm != cpu_v7_iciallu_switch_mm) + goto bl_error;per_cpu (harden_branch_predictor_fn, cpu) = harden_branch_predictor_iciallu; spectre_v2_method ="ICIALLU" ;
@@ -82,6 +88,8 @@ static void cpu_v7_spectre_init(void) ARM_SMCCC_ARCH_WORKAROUND_1, &res);if ((int )res.a0 !=0 )break ; +if (processor.switch_mm != cpu_v7_hvc_switch_mm && cpu) + goto bl_error;per_cpu (harden_branch_predictor_fn, cpu) = call_hvc_arch_workaround_1; processor.switch_mm = cpu_v7_hvc_switch_mm;
@@ -93,6 +101,8 @@ static void cpu_v7_spectre_init(void) ARM_SMCCC_ARCH_WORKAROUND_1, &res);if ((int )res.a0 !=0 )break ; +if (processor.switch_mm != cpu_v7_smc_switch_mm && cpu) + goto bl_error;per_cpu (harden_branch_predictor_fn, cpu) = call_smc_arch_workaround_1; processor.switch_mm = cpu_v7_smc_switch_mm;
@@ -109,6 +119,11 @@ static void cpu_v7_spectre_init(void)if (spectre_v2_method)pr_info ("CPU%u: Spectre v2: using %s workaround\n" ,smp_processor_id (), spectre_v2_method); +return ; + +bl_error: +pr_err ("CPU%u: Spectre v2: incorrect context switching function, system vulnerable\n" , + cpu); }#else static void cpu_v7_spectre_init (void )
Greg Kroah-Hartman
maintainerPATCH 50/75 ARM: spectre-v1: add speculation barrier (csdb) macros
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
Commit a78d156587931a2c3b354534aa772febf6c9e855 upstream.
Add assembly and C macros for the new CSDB instruction.
--- arch/arm/include/asm/assembler.h | 8 ++++++++ arch/arm/include/asm/barrier.h | 13 +++++++++++++ 2 files changed, 21 insertions(+)
arch/arm/include/asm/assembler.h +8 -0
@@ -441,6 +441,14 @@ THUMB( orr \reg , \reg , #PSR_T_BIT ) .size \name , . - \name .endm + .macro csdb +#ifdef CONFIG_THUMB2_KERNEL + .inst.w 0xf3af8014 +#else + .inst 0xe320f014 +#endif + .endm + .macro check_uaccess, addr:req, size:req, limit:req, tmp:req, bad:req#ifndef CONFIG_CPU_USE_DOMAINS adds \tmp, \addr, #\size - 1
arch/arm/include/asm/barrier.h +13 -0
@@ -18,6 +18,12 @@#define isb (option) __asm__ __volatile__ ("isb " #option : : : "memory")#define dsb (option) __asm__ __volatile__ ("dsb " #option : : : "memory")#define dmb (option) __asm__ __volatile__ ("dmb " #option : : : "memory") +#ifdef CONFIG_THUMB2_KERNEL +#define CSDB ".inst.w 0xf3af8014" +#else +#define CSDB ".inst 0xe320f014" +#endif +#define csdb () __asm__ __volatile__(CSDB : : : "memory")#elif defined(CONFIG_CPU_XSC3 ) || __LINUX_ARM_ARCH__ ==6 #define isb (x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \ : : "r" (0) : "memory")
@@ -38,6 +44,13 @@#define dmb (x) __asm__ __volatile__ ("" : : : "memory")#endif +#ifndef CSDB +#define CSDB +#endif +#ifndef csdb +#define csdb () +#endif +#ifdef CONFIG_ARM_HEAVY_MB extern void (*soc_mb)(void );extern void arm_heavy_mb (void );
Greg Kroah-Hartman
maintainerPATCH 51/75 ARM: spectre-v1: add array_index_mask_nospec() implementation
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
Commit 1d4238c56f9816ce0f9c8dbe42d7f2ad81cb6613 upstream.
Add an implementation of the array_index_mask_nospec() function for mitigating Spectre variant 1 throughout the kernel.
--- arch/arm/include/asm/barrier.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
arch/arm/include/asm/barrier.h +21 -0
@@ -108,5 +108,26 @@ do { \#define smp_mb__before_atomic () smp_mb()#define smp_mb__after_atomic () smp_mb() +#ifdef CONFIG_CPU_SPECTRE +static inline unsigned long array_index_mask_nospec (unsigned long idx, +unsigned long sz) +{ +unsigned long mask; + + asmvolatile ( +"cmp %1, %2\n" +" sbc %0, %1, %1\n" +CSDB + :"=r" (mask) + :"r" (idx),"Ir" (sz) + :"cc" ); + +return mask; +} +#define array_index_mask_nospec array_index_mask_nospec +#endif + +#include <asm-generic/barrier.h> +#endif /* !__ASSEMBLY__ */ #endif /* __ASM_BARRIER_H */
Greg Kroah-Hartman
maintainerPATCH 52/75 ARM: spectre-v1: fix syscall entry
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
Commit 10573ae547c85b2c61417ff1a106cffbfceada35 upstream.
Prevent speculation at the syscall table decoding by clamping the index used to zero on invalid system call numbers, and using the csdb speculative barrier.
--- arch/arm/kernel/entry-common.S | 18 +++++++----------- arch/arm/kernel/entry-header.S | 25 +++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 11 deletions(-)
arch/arm/kernel/entry-common.S +7 -11
@@ -223,9 +223,7 @@ local_restart: tst r10, #_TIF_SYSCALL_WORK @ are we tracing syscalls? bne __sys_trace - cmp scno, #NR_syscalls @ check upper syscall limit - badr lr, ret_fast_syscall @ return address - ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine + invoke_syscall tbl, scno, r10, ret_fast_syscall add r1, sp, #S_OFF 2: cmp scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE)
@@ -258,14 +256,8 @@ __sys_trace: mov r1, scno add r0, sp, #S_OFF bl syscall_trace_enter - - badr lr, __sys_trace_return @ return address - mov scno, r0 @ syscall number (possibly new) - add r1, sp, #S_R0 + S_OFF @ pointer to regs - cmp scno, #NR_syscalls @ check upper syscall limit - ldmccia r1, {r0 - r6} @ have to reload r0 - r6 - stmccia sp, {r4, r5} @ and update the stack args - ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine + mov scno, r0 + invoke_syscall tbl, scno, r10, __sys_trace_return, reload=1 cmp scno, #-1 @ skip the syscall? bne 2b add sp, sp, #S_OFF @ restore stack
@@ -317,6 +309,10 @@ sys_syscall: bic scno, r0, #__NR_OABI_SYSCALL_BASE cmp scno, #__NR_syscall - __NR_SYSCALL_BASE cmpne scno, #NR_syscalls @ check range +#ifdef CONFIG_CPU_SPECTRE + movhs scno, #0 + csdb +#endif stmloia sp, {r5, r6} @ shuffle args movlo r0, r1 movlo r1, r2
arch/arm/kernel/entry-header.S +25 -0
@@ -373,6 +373,31 @@ #endif .endm + .macro invoke_syscall, table, nr, tmp, ret, reload=0 +#ifdef CONFIG_CPU_SPECTRE + mov \tmp, \nr + cmp \tmp, #NR_syscalls @ check upper syscall limit + movcs \tmp, #0 + csdb + badr lr, \ret @ return address + .if \reload + add r1, sp, #S_R0 + S_OFF @ pointer to regs + ldmccia r1, {r0 - r6} @ reload r0-r6 + stmccia sp, {r4, r5} @ update stack arguments + .endif + ldrcc pc, [\table, \tmp, lsl #2] @ call sys_* routine +#else + cmp \nr, #NR_syscalls @ check upper syscall limit + badr lr, \ret @ return address + .if \reload + add r1, sp, #S_R0 + S_OFF @ pointer to regs + ldmccia r1, {r0 - r6} @ reload r0-r6 + stmccia sp, {r4, r5} @ update stack arguments + .endif + ldrcc pc, [\table, \nr, lsl #2] @ call sys_* routine +#endif + .endm + /* * These are the registers used in the syscall handler, and allow us to * have in theory up to 7 arguments to a function - r0 to r6.
Greg Kroah-Hartman
maintainerPATCH 53/75 ARM: signal: copy registers using __copy_from_user()
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
Commit c32cd419d6650e42b9cdebb83c672ec945e6bd7e upstream.
__get_user_error() is used as a fast accessor to make copying structure members in the signal handling path as efficient as possible. However, with software PAN and the recent Spectre variant 1, the efficiency is reduced as these are no longer fast accessors.
In the case of software PAN, it has to switch the domain register around each access, and with Spectre variant 1, it would have to repeat the access_ok() check for each access.
It becomes much more efficient to use __copy_from_user() instead, so let's use this for the ARM integer registers.
--- arch/arm/kernel/signal.c | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-)
arch/arm/kernel/signal.c +21 -17
@@ -141,6 +141,7 @@ struct rt_sigframe {static int restore_sigframe (struct pt_regs *regs,struct sigframe __user *sf) { +struct sigcontext context;struct aux_sigframe __user *aux;sigset_t set;int err;
@@ -149,23 +150,26 @@ static int restore_sigframe(struct pt_reif (err ==0 )set_current_blocked (&set); -__get_user_error (regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err); -__get_user_error (regs->ARM_r1, &sf->uc.uc_mcontext.arm_r1, err); -__get_user_error (regs->ARM_r2, &sf->uc.uc_mcontext.arm_r2, err); -__get_user_error (regs->ARM_r3, &sf->uc.uc_mcontext.arm_r3, err); -__get_user_error (regs->ARM_r4, &sf->uc.uc_mcontext.arm_r4, err); -__get_user_error (regs->ARM_r5, &sf->uc.uc_mcontext.arm_r5, err); -__get_user_error (regs->ARM_r6, &sf->uc.uc_mcontext.arm_r6, err); -__get_user_error (regs->ARM_r7, &sf->uc.uc_mcontext.arm_r7, err); -__get_user_error (regs->ARM_r8, &sf->uc.uc_mcontext.arm_r8, err); -__get_user_error (regs->ARM_r9, &sf->uc.uc_mcontext.arm_r9, err); -__get_user_error (regs->ARM_r10, &sf->uc.uc_mcontext.arm_r10, err); -__get_user_error (regs->ARM_fp, &sf->uc.uc_mcontext.arm_fp, err); -__get_user_error (regs->ARM_ip, &sf->uc.uc_mcontext.arm_ip, err); -__get_user_error (regs->ARM_sp, &sf->uc.uc_mcontext.arm_sp, err); -__get_user_error (regs->ARM_lr, &sf->uc.uc_mcontext.arm_lr, err); -__get_user_error (regs->ARM_pc, &sf->uc.uc_mcontext.arm_pc, err); -__get_user_error (regs->ARM_cpsr, &sf->uc.uc_mcontext.arm_cpsr, err); + err |=__copy_from_user (&context, &sf->uc.uc_mcontext,sizeof (context)); +if (err ==0 ) { + regs->ARM_r0 = context.arm_r0; + regs->ARM_r1 = context.arm_r1; + regs->ARM_r2 = context.arm_r2; + regs->ARM_r3 = context.arm_r3; + regs->ARM_r4 = context.arm_r4; + regs->ARM_r5 = context.arm_r5; + regs->ARM_r6 = context.arm_r6; + regs->ARM_r7 = context.arm_r7; + regs->ARM_r8 = context.arm_r8; + regs->ARM_r9 = context.arm_r9; + regs->ARM_r10 = context.arm_r10; + regs->ARM_fp = context.arm_fp; + regs->ARM_ip = context.arm_ip; + regs->ARM_sp = context.arm_sp; + regs->ARM_lr = context.arm_lr; + regs->ARM_pc = context.arm_pc; + regs->ARM_cpsr = context.arm_cpsr; + } err |= !valid_user_regs (regs);
Greg Kroah-Hartman
maintainerPATCH 54/75 ARM: vfp: use __copy_from_user() when restoring VFP state
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
Commit 42019fc50dfadb219f9e6ddf4c354f3837057d80 upstream.
__get_user_error() is used as a fast accessor to make copying structure members in the signal handling path as efficient as possible. However, with software PAN and the recent Spectre variant 1, the efficiency is reduced as these are no longer fast accessors.
In the case of software PAN, it has to switch the domain register around each access, and with Spectre variant 1, it would have to repeat the access_ok() check for each access.
Use __copy_from_user() rather than __get_user_err() for individual members when restoring VFP state.
--- arch/arm/include/asm/thread_info.h | 4 ++-- arch/arm/kernel/signal.c | 17 ++++++++--------- arch/arm/vfp/vfpmodule.c | 17 +++++++---------- 3 files changed, 17 insertions(+), 21 deletions(-)
arch/arm/include/asm/thread_info.h +2 -2
@@ -126,8 +126,8 @@ struct user_vfp_exc;extern int vfp_preserve_user_clear_hwstate (struct user_vfp __user *,struct user_vfp_exc __user *); -extern int vfp_restore_user_hwstate (struct user_vfp __user *, -struct user_vfp_exc __user *); +extern int vfp_restore_user_hwstate (struct user_vfp *, +struct user_vfp_exc *);#endif /*
arch/arm/kernel/signal.c +8 -9
@@ -107,21 +107,20 @@ static int preserve_vfp_context(struct v return vfp_preserve_user_clear_hwstate(&frame->ufp, &frame->ufp_exc); } -static int restore_vfp_context (struct vfp_sigframe __user *frame) +static int restore_vfp_context (struct vfp_sigframe __user *auxp) { -unsigned long magic; -unsigned long size; -int err =0 ; +struct vfp_sigframe frame; +int err; -__get_user_error (magic, &frame->magic, err); -__get_user_error (size, &frame->size, err); + err =__copy_from_user (&frame, (char __user *) auxp,sizeof (frame));if (err) -return -EFAULT ; -if (magic !=VFP_MAGIC || size !=VFP_STORAGE_SIZE ) +return err; + +if (frame.magic !=VFP_MAGIC || frame.size !=VFP_STORAGE_SIZE )return -EINVAL ; -return vfp_restore_user_hwstate (&frame->ufp, &frame->ufp_exc); +return vfp_restore_user_hwstate (&frame.ufp, &frame.ufp_exc); }#endif
arch/arm/vfp/vfpmodule.c +7 -10
@@ -601,13 +601,11 @@ int vfp_preserve_user_clear_hwstate(stru }/* Sanitise and restore the current VFP state from the provided structures. */ -int vfp_restore_user_hwstate (struct user_vfp __user *ufp, -struct user_vfp_exc __user *ufp_exc) +int vfp_restore_user_hwstate (struct user_vfp *ufp,struct user_vfp_exc *ufp_exc) {struct thread_info *thread =current_thread_info ();struct vfp_hard_struct *hwstate = &thread->vfpstate.hard;unsigned long fpexc; -int err =0 ;/* Disable VFP to avoid corrupting the new thread state. */ vfp_flush_hwstate (thread);
@@ -616,17 +614,16 @@ int vfp_restore_user_hwstate(struct user* Copy the floating point registers. There can be unused * registers see asm/hwcap.h for details. */ - err |=__copy_from_user (&hwstate->fpregs, &ufp->fpregs, -sizeof (hwstate->fpregs)); +memcpy (&hwstate->fpregs, &ufp->fpregs,sizeof (hwstate->fpregs));/* * Copy the status and control register. */ -__get_user_error (hwstate->fpscr, &ufp->fpscr, err); + hwstate->fpscr = ufp->fpscr;/* * Sanitise and restore the exception registers. */ -__get_user_error (fpexc, &ufp_exc->fpexc, err); + fpexc = ufp_exc->fpexc;/* Ensure the VFP is enabled. */ fpexc |=FPEXC_EN ;
@@ -635,10 +632,10 @@ int vfp_restore_user_hwstate(struct user fpexc &= ~(FPEXC_EX |FPEXC_FP2V ); hwstate->fpexc = fpexc; -__get_user_error (hwstate->fpinst, &ufp_exc->fpinst, err); -__get_user_error (hwstate->fpinst2, &ufp_exc->fpinst2, err); + hwstate->fpinst = ufp_exc->fpinst; + hwstate->fpinst2 = ufp_exc->fpinst2; -return err ? -EFAULT :0 ; +return 0 ; }/*
Greg Kroah-Hartman
maintainerPATCH 55/75 ARM: oabi-compat: copy semops using __copy_from_user()
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
Commit 8c8484a1c18e3231648f5ba7cc5ffb7fd70b3ca4 upstream.
__get_user_error() is used as a fast accessor to make copying structure members as efficient as possible. However, with software PAN and the recent Spectre variant 1, the efficiency is reduced as these are no longer fast accessors.
In the case of software PAN, it has to switch the domain register around each access, and with Spectre variant 1, it would have to repeat the access_ok() check for each access.
Rather than using __get_user_error() to copy each semops element member, copy each semops element in full using __copy_from_user().
--- arch/arm/kernel/sys_oabi-compat.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
arch/arm/kernel/sys_oabi-compat.c +5 -3
@@ -328,9 +328,11 @@ asmlinkage long sys_oabi_semtimedop(intreturn -ENOMEM ; err =0 ;for (i =0 ; i < nsops; i++) { -__get_user_error (sops[i].sem_num, &tsops->sem_num, err); -__get_user_error (sops[i].sem_op, &tsops->sem_op, err); -__get_user_error (sops[i].sem_flg, &tsops->sem_flg, err); +struct oabi_sembuf osb; + err |=__copy_from_user (&osb, tsops,sizeof (osb)); + sops[i].sem_num = osb.sem_num; + sops[i].sem_op = osb.sem_op; + sops[i].sem_flg = osb.sem_flg; tsops++; }if (timeout) {
Greg Kroah-Hartman
maintainerPATCH 56/75 ARM: use __inttype() in get_user()
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
Commit d09fbb327d670737ab40fd8bbb0765ae06b8b739 upstream.
Borrow the x86 implementation of __inttype() to use in get_user() to select an integer type suitable to temporarily hold the result value. This is necessary to avoid propagating the volatile nature of the result argument, which can cause the following warning:
lib/iov_iter.c:413:5: warning: optimization may eliminate reads and/or writes to register variables [-Wvolatile-register-var]
--- arch/arm/include/asm/uaccess.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
arch/arm/include/asm/uaccess.h +8 -1
@@ -123,6 +123,13 @@ static inline void set_fs(mm_segment_t f flag; })/* +* This is a type: either unsigned long, if the argument fits into +* that type, or otherwise unsigned long long. +*/ +#define __inttype (x) \ + __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL)) + +/* * Single-value transfer routines. They automatically use the right * size if we just have the right pointer type. Note that the functions * which read from user space (*get_*) need to take care not to leak
@@ -191,7 +198,7 @@ extern int __get_user_64t_4(void *); ({ \ unsigned long __limit = current_thread_info()->addr_limit - 1; \ register const typeof(*(p)) __user *__p asm("r0") = (p);\ - register typeof(x) __r2 asm("r2"); \ + register __inttype(x) __r2 asm("r2"); \ register unsigned long __l asm("r1") = __limit; \ register int __e asm("r0"); \ unsigned int __ua_flags = uaccess_save_and_enable(); \
Greg Kroah-Hartman
maintainerPATCH 57/75 ARM: spectre-v1: use get_user() for __get_user()
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
Commit b1cd0a14806321721aae45f5446ed83a3647c914 upstream.
Fixing __get_user() for spectre variant 1 is not sane: we would have to add address space bounds checking in order to validate that the location should be accessed, and then zero the address if found to be invalid.
Since __get_user() is supposed to avoid the bounds check, and this is exactly what get_user() does, there's no point having two different implementations that are doing the same thing. So, when the Spectre workarounds are required, make __get_user() an alias of get_user().
--- arch/arm/include/asm/uaccess.h | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
arch/arm/include/asm/uaccess.h +11 -6
@@ -288,6 +288,16 @@ static inline void set_fs(mm_segment_t f#define user_addr_max () \ (segment_eq(get_fs(), KERNEL_DS) ? ~0UL : get_fs()) +#ifdef CONFIG_CPU_SPECTRE +/* +* When mitigating Spectre variant 1, it is not worth fixing the non- +* verifying accessors, because we need to add verification of the +* address space there. Force these to use the standard get_user() +* version instead. +*/ +#define __get_user (x, ptr) get_user(x, ptr) +#else +/* * The "__xxx" versions of the user access functions do not verify the * address space - it must have been done previously with a separate
@@ -304,12 +314,6 @@ static inline void set_fs(mm_segment_t f __gu_err; \ }) -#define __get_user_error (x, ptr, err) \ -({ \ - __get_user_err((x), (ptr), err); \ - (void) 0; \ -}) -#define __get_user_err (x, ptr, err) \ do { \ unsigned long __gu_addr = (unsigned long)(ptr); \
@@ -369,6 +373,7 @@ do { \#define __get_user_asm_word (x, addr, err) \ __get_user_asm(x, addr, err, ldr) +#endif #define __put_user_switch (x, ptr, __err, __fn) \
Greg Kroah-Hartman
maintainerPATCH 58/75 ARM: spectre-v1: mitigate user accesses
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
Commit a3c0f84765bb429ba0fd23de1c57b5e1591c9389 upstream.
Spectre variant 1 attacks are about this sequence of pseudo-code:
index = load(user-manipulated pointer); access(base + index * stride);
In order for the cache side-channel to work, the access() must me made to memory which userspace can detect whether cache lines have been loaded. On 32-bit ARM, this must be either user accessible memory, or a kernel mapping of that same user accessible memory.
The problem occurs when the load() speculatively loads privileged data, and the subsequent access() is made to user accessible memory.
Any load() which makes use of a user-maniplated pointer is a potential problem if the data it has loaded is used in a subsequent access. This also applies for the access() if the data loaded by that access is used by a subsequent access.
Harden the get_user() accessors against Spectre attacks by forcing out of bounds addresses to a NULL pointer. This prevents get_user() being used as the load() step above. As a side effect, put_user() will also be affected even though it isn't implicated.
Also harden copy_from_user() by redoing the bounds check within the arm_copy_from_user() code, and NULLing the pointer if out of bounds.
--- arch/arm/include/asm/assembler.h | 4 ++++ arch/arm/lib/copy_from_user.S | 9 +++++++++ 2 files changed, 13 insertions(+)
arch/arm/include/asm/assembler.h +4 -0
@@ -454,6 +454,10 @@ THUMB( orr \reg , \reg , #PSR_T_BIT ) adds \tmp, \addr, #\size - 1 sbcccs \tmp, \tmp, \limit bcs \bad +#ifdef CONFIG_CPU_SPECTRE + movcs \addr, #0 + csdb +#endif #endif .endm
arch/arm/lib/copy_from_user.S +9 -0
@@ -90,6 +90,15 @@ .text ENTRY(arm_copy_from_user) +#ifdef CONFIG_CPU_SPECTRE + get_thread_info r3 + ldr r3, [r3, #TI_ADDR_LIMIT] + adds ip, r1, r2 @ ip=addr+size + sub r3, r3, #1 @ addr_limit - 1 + cmpcc ip, r3 @ if (addr+size > addr_limit - 1) + movcs r1, #0 @ addr = NULL + csdb +#endif #include "copy_template.S"
Greg Kroah-Hartman
maintainerPATCH 59/75 ARM: 8789/1: signal: copy registers using __copy_to_user()
In reply to Greg Kroah-HartmanFrom: Julien Thierry <[email protected]>
Commit 5ca451cf6ed04443774bbb7ee45332dafa42e99f upstream.
When saving the ARM integer registers, use __copy_to_user() to copy them into user signal frame, rather than __put_user_error(). This has the benefit of disabling/enabling PAN once for the whole copy intead of once per write.
--- arch/arm/kernel/signal.c | 47 ++++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 21 deletions(-)
arch/arm/kernel/signal.c +26 -21
@@ -256,30 +256,35 @@ static int setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set) { struct aux_sigframe __user *aux; +struct sigcontext context;int err =0 ; -__put_user_error (regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err); -__put_user_error (regs->ARM_r1, &sf->uc.uc_mcontext.arm_r1, err); -__put_user_error (regs->ARM_r2, &sf->uc.uc_mcontext.arm_r2, err); -__put_user_error (regs->ARM_r3, &sf->uc.uc_mcontext.arm_r3, err); -__put_user_error (regs->ARM_r4, &sf->uc.uc_mcontext.arm_r4, err); -__put_user_error (regs->ARM_r5, &sf->uc.uc_mcontext.arm_r5, err); -__put_user_error (regs->ARM_r6, &sf->uc.uc_mcontext.arm_r6, err); -__put_user_error (regs->ARM_r7, &sf->uc.uc_mcontext.arm_r7, err); -__put_user_error (regs->ARM_r8, &sf->uc.uc_mcontext.arm_r8, err); -__put_user_error (regs->ARM_r9, &sf->uc.uc_mcontext.arm_r9, err); -__put_user_error (regs->ARM_r10, &sf->uc.uc_mcontext.arm_r10, err); -__put_user_error (regs->ARM_fp, &sf->uc.uc_mcontext.arm_fp, err); -__put_user_error (regs->ARM_ip, &sf->uc.uc_mcontext.arm_ip, err); -__put_user_error (regs->ARM_sp, &sf->uc.uc_mcontext.arm_sp, err); -__put_user_error (regs->ARM_lr, &sf->uc.uc_mcontext.arm_lr, err); -__put_user_error (regs->ARM_pc, &sf->uc.uc_mcontext.arm_pc, err); -__put_user_error (regs->ARM_cpsr, &sf->uc.uc_mcontext.arm_cpsr, err); + context = (struct sigcontext ) { + .arm_r0 = regs->ARM_r0, + .arm_r1 = regs->ARM_r1, + .arm_r2 = regs->ARM_r2, + .arm_r3 = regs->ARM_r3, + .arm_r4 = regs->ARM_r4, + .arm_r5 = regs->ARM_r5, + .arm_r6 = regs->ARM_r6, + .arm_r7 = regs->ARM_r7, + .arm_r8 = regs->ARM_r8, + .arm_r9 = regs->ARM_r9, + .arm_r10 = regs->ARM_r10, + .arm_fp = regs->ARM_fp, + .arm_ip = regs->ARM_ip, + .arm_sp = regs->ARM_sp, + .arm_lr = regs->ARM_lr, + .arm_pc = regs->ARM_pc, + .arm_cpsr = regs->ARM_cpsr, -__put_user_error (current->thread.trap_no, &sf->uc.uc_mcontext.trap_no, err); -__put_user_error (current->thread.error_code, &sf->uc.uc_mcontext.error_code, err); -__put_user_error (current->thread.address, &sf->uc.uc_mcontext.fault_address, err); -__put_user_error (set->sig[0 ], &sf->uc.uc_mcontext.oldmask, err); + .trap_no = current->thread.trap_no, + .error_code = current->thread.error_code, + .fault_address = current->thread.address, + .oldmask = set->sig[0 ], + }; + + err |=__copy_to_user (&sf->uc.uc_mcontext, &context,sizeof (context)); err |=__copy_to_user (&sf->uc.uc_sigmask, set,sizeof (*set));
Greg Kroah-Hartman
maintainerPATCH 60/75 ARM: 8791/1: vfp: use __copy_to_user() when saving VFP state
In reply to Greg Kroah-HartmanFrom: Julien Thierry <[email protected]>
Commit 3aa2df6ec2ca6bc143a65351cca4266d03a8bc41 upstream.
Use __copy_to_user() rather than __put_user_error() for individual members when saving VFP state.
This has the benefit of disabling/enabling PAN once per copied struct intead of once per write.
--- arch/arm/include/asm/thread_info.h | 4 ++-- arch/arm/kernel/signal.c | 13 +++++++------ arch/arm/vfp/vfpmodule.c | 20 ++++++++------------ 3 files changed, 17 insertions(+), 20 deletions(-)
arch/arm/include/asm/thread_info.h +2 -2
@@ -124,8 +124,8 @@ extern void vfp_flush_hwstate(struct thrstruct user_vfp ;struct user_vfp_exc ; -extern int vfp_preserve_user_clear_hwstate (struct user_vfp __user *, -struct user_vfp_exc __user *); +extern int vfp_preserve_user_clear_hwstate (struct user_vfp *, +struct user_vfp_exc *);extern int vfp_restore_user_hwstate (struct user_vfp *,struct user_vfp_exc *);#endif
arch/arm/kernel/signal.c +7 -6
@@ -94,17 +94,18 @@ static int restore_iwmmxt_context(structstatic int preserve_vfp_context (struct vfp_sigframe __user *frame) { -const unsigned long magic =VFP_MAGIC ; -const unsigned long size =VFP_STORAGE_SIZE ; +struct vfp_sigframe kframe;int err =0 ; -__put_user_error (magic, &frame->magic, err); -__put_user_error (size, &frame->size, err); +memset (&kframe,0 ,sizeof (kframe)); + kframe.magic =VFP_MAGIC ; + kframe.size =VFP_STORAGE_SIZE ; + err =vfp_preserve_user_clear_hwstate (&kframe.ufp, &kframe.ufp_exc);if (err) -return -EFAULT ; +return err; -return vfp_preserve_user_clear_hwstate (&frame->ufp, &frame->ufp_exc); +return __copy_to_user (frame, &kframe,sizeof (kframe)); }static int restore_vfp_context (struct vfp_sigframe __user *auxp)
arch/arm/vfp/vfpmodule.c +8 -12
@@ -558,12 +558,11 @@ void vfp_flush_hwstate(struct thread_inf* Save the current VFP state into the provided structures and prepare * for entry into a new function (signal handler). */ -int vfp_preserve_user_clear_hwstate (struct user_vfp __user *ufp, -struct user_vfp_exc __user *ufp_exc) +int vfp_preserve_user_clear_hwstate (struct user_vfp *ufp, +struct user_vfp_exc *ufp_exc) {struct thread_info *thread =current_thread_info ();struct vfp_hard_struct *hwstate = &thread->vfpstate.hard; -int err =0 ;/* Ensure that the saved hwstate is up-to-date. */ vfp_sync_hwstate (thread);
@@ -572,22 +571,19 @@ int vfp_preserve_user_clear_hwstate(stru* Copy the floating point registers. There can be unused * registers see asm/hwcap.h for details. */ - err |=__copy_to_user (&ufp->fpregs, &hwstate->fpregs, -sizeof (hwstate->fpregs)); +memcpy (&ufp->fpregs, &hwstate->fpregs,sizeof (hwstate->fpregs)); +/* * Copy the status and control register. */ -__put_user_error (hwstate->fpscr, &ufp->fpscr, err); + ufp->fpscr = hwstate->fpscr;/* * Copy the exception registers. */ -__put_user_error (hwstate->fpexc, &ufp_exc->fpexc, err); -__put_user_error (hwstate->fpinst, &ufp_exc->fpinst, err); -__put_user_error (hwstate->fpinst2, &ufp_exc->fpinst2, err); - -if (err) -return -EFAULT ; + ufp_exc->fpexc = hwstate->fpexc; + ufp_exc->fpinst = hwstate->fpinst; + ufp_exc->fpinst2 = ufp_exc->fpinst2;/* Ensure that VFP is disabled. */ vfp_flush_hwstate (thread);
Greg Kroah-Hartman
maintainerPATCH 61/75 ARM: 8792/1: oabi-compat: copy oabi events using __copy_to_user()
In reply to Greg Kroah-HartmanFrom: Julien Thierry <[email protected]>
Commit 319508902600c2688e057750148487996396e9ca upstream.
Copy events to user using __copy_to_user() rather than copy members of individually with __put_user_error().
This has the benefit of disabling/enabling PAN once per event intead of once per event member.
--- arch/arm/kernel/sys_oabi-compat.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
arch/arm/kernel/sys_oabi-compat.c +6 -2
@@ -276,6 +276,7 @@ asmlinkage long sys_oabi_epoll_wait(int int maxevents, int timeout) {struct epoll_event *kbuf; +struct oabi_epoll_event e;mm_segment_t fs;long ret, err, i;
@@ -294,8 +295,11 @@ asmlinkage long sys_oabi_epoll_wait(intset_fs (fs); err =0 ;for (i =0 ; i < ret; i++) { -__put_user_error (kbuf[i].events, &events->events, err); -__put_user_error (kbuf[i].data, &events->data, err); + e.events = kbuf[i].events; + e.data = kbuf[i].data; + err =__copy_to_user (events, &e,sizeof (e)); +if (err) +break ; events++; }kfree (kbuf);
Greg Kroah-Hartman
maintainerPATCH 62/75 ARM: 8793/1: signal: replace __put_user_error with __put_user
In reply to Greg Kroah-HartmanFrom: Julien Thierry <[email protected]>
Commit 18ea66bd6e7a95bdc598223d72757190916af28b upstream.
With Spectre-v1.1 mitigations, __put_user_error is pointless. In an attempt to remove it, replace its references in frame setups with __put_user.
--- arch/arm/kernel/signal.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
arch/arm/kernel/signal.c +4 -4
@@ -302,7 +302,7 @@ setup_sigframe(struct sigframe __user *sif (err ==0 ) err |=preserve_vfp_context (&aux->vfp);#endif -__put_user_error (0 , &aux->end_magic, err); + err |=__put_user (0 , &aux->end_magic);return err; }
@@ -434,7 +434,7 @@ setup_frame(struct ksignal *ksig, sigset/* * Set uc.uc_flags to a value which sc.trap_no would never have. */ -__put_user_error (0x5ac3c35a , &frame->uc.uc_flags, err); + err =__put_user (0x5ac3c35a , &frame->uc.uc_flags); err |=setup_sigframe (frame, regs, set);if (err ==0 )
@@ -454,8 +454,8 @@ setup_rt_frame(struct ksignal *ksig, sig err |=copy_siginfo_to_user (&frame->info, &ksig->info); -__put_user_error (0 , &frame->sig.uc.uc_flags, err); -__put_user_error (NULL , &frame->sig.uc.uc_link, err); + err |=__put_user (0 , &frame->sig.uc.uc_flags); + err |=__put_user (NULL , &frame->sig.uc.uc_link); err |=__save_altstack (&frame->sig.uc.uc_stack, regs->ARM_sp); err |=setup_sigframe (&frame->sig, regs, set);
Greg Kroah-Hartman
maintainerPATCH 63/75 ARM: 8794/1: uaccess: Prevent speculative use of the current addr_limit
In reply to Greg Kroah-HartmanFrom: Julien Thierry <[email protected]>
Commit 621afc677465db231662ed126ae1f355bf8eac47 upstream.
A mispredicted conditional call to set_fs could result in the wrong addr_limit being forwarded under speculation to a subsequent access_ok check, potentially forming part of a spectre-v1 attack using uaccess routines.
This patch prevents this forwarding from taking place, but putting heavy barriers in set_fs after writing the addr_limit.
Porting commit c2f0ad4fc089cff8 ("arm64: uaccess: Prevent speculative use of the current addr_limit").
--- arch/arm/include/asm/uaccess.h | 8 ++++++++ 1 file changed, 8 insertions(+)
arch/arm/include/asm/uaccess.h +8 -0
@@ -99,6 +99,14 @@ extern int __put_user_bad(void);static inline void set_fs (mm_segment_t fs) {current_thread_info ()->addr_limit = fs; + +/* +* Prevent a mispredicted conditional call to set_fs from forwarding +* the wrong address limit to access_ok under speculation. +*/ +dsb (nsh); +isb (); +modify_domain (DOMAIN_KERNEL , fs ?DOMAIN_CLIENT :DOMAIN_MANAGER ); }
Greg Kroah-Hartman
maintainerPATCH 64/75 ARM: 8795/1: spectre-v1.1: use put_user() for __put_user()
In reply to Greg Kroah-HartmanFrom: Julien Thierry <[email protected]>
Commit e3aa6243434fd9a82e84bb79ab1abd14f2d9a5a7 upstream.
When Spectre mitigation is required, __put_user() needs to include check_uaccess. This is already the case for put_user(), so just make __put_user() an alias of put_user().
--- arch/arm/include/asm/uaccess.h | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
arch/arm/include/asm/uaccess.h +9 -6
@@ -408,6 +408,14 @@ do { \ __pu_err; \ }) +#ifdef CONFIG_CPU_SPECTRE +/* +* When mitigating Spectre variant 1.1, all accessors need to include +* verification of the address space. +*/ +#define __put_user (x, ptr) put_user(x, ptr) + +#else #define __put_user (x, ptr) \ ({ \ long __pu_err = 0; \
@@ -415,12 +423,6 @@ do { \ __pu_err; \ }) -#define __put_user_error (x, ptr, err) \ -({ \ - __put_user_switch((x), (ptr), (err), __put_user_nocheck); \ - (void) 0; \ -}) -#define __put_user_nocheck (x, __pu_ptr, __err, __size) \ do { \ unsigned long __pu_addr = (unsigned long)__pu_ptr; \
@@ -500,6 +502,7 @@ do { \ : "r" (x), "i" (-EFAULT) \ : "cc") +#endif /* !CONFIG_CPU_SPECTRE */ #ifdef CONFIG_MMU extern unsigned long __must_check
Greg Kroah-Hartman
maintainerPATCH 65/75 ARM: 8796/1: spectre-v1,v1.1: provide helpers for address sanitization
In reply to Greg Kroah-HartmanFrom: Julien Thierry <[email protected]>
Commit afaf6838f4bc896a711180b702b388b8cfa638fc upstream.
Introduce C and asm helpers to sanitize user address, taking the address range they target into account.
Use asm helper for existing sanitization in __copy_from_user().
--- arch/arm/include/asm/assembler.h | 11 +++++++++++ arch/arm/include/asm/uaccess.h | 26 ++++++++++++++++++++++++++ arch/arm/lib/copy_from_user.S | 6 +----- 3 files changed, 38 insertions(+), 5 deletions(-)
arch/arm/include/asm/assembler.h +11 -0
@@ -461,6 +461,17 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )#endif .endm + .macro uaccess_mask_range_ptr, addr:req, size:req, limit:req, tmp:req +#ifdef CONFIG_CPU_SPECTRE + sub \tmp, \limit, #1 + subs \tmp, \tmp, \addr @ tmp = limit - 1 - addr + addhs \tmp, \tmp, #1 @ if (tmp >= 0) { + subhss \tmp, \tmp, \size @ tmp = limit - (addr + size) } + movlo \addr, #0 @ if (tmp < 0) addr = NULL + csdb +#endif + .endm + .macro uaccess_disable, tmp, isb=1 #ifdef CONFIG_CPU_SW_DOMAIN_PAN/*
arch/arm/include/asm/uaccess.h +26 -0
@@ -138,6 +138,32 @@ static inline void set_fs(mm_segment_t f__typeof__ (__builtin_choose_expr (sizeof (x) >sizeof (0UL ),0ULL ,0UL ))/* +* Sanitise a uaccess pointer such that it becomes NULL if addr+size +* is above the current addr_limit. + */ +#define uaccess_mask_range_ptr (ptr, size) \ + ((__typeof__(ptr))__uaccess_mask_range_ptr(ptr, size)) +static inline void __user *__uaccess_mask_range_ptr (const void __user *ptr, +size_t size) +{ +void __user *safe_ptr = (void __user *)ptr; +unsigned long tmp; + + asmvolatile ( +" sub %1, %3, #1\n" +" subs %1, %1, %0\n" +" addhs %1, %1, #1\n" +" subhss %1, %1, %2\n" +" movlo %0, #0\n" + :"+r" (safe_ptr),"=&r" (tmp) + :"r" (size),"r" (current_thread_info ()->addr_limit) + :"cc" ); + +csdb (); +return safe_ptr; +} + +/* * Single-value transfer routines. They automatically use the right * size if we just have the right pointer type. Note that the functions * which read from user space (*get_*) need to take care not to leak
arch/arm/lib/copy_from_user.S +1 -5
@@ -93,11 +93,7 @@ ENTRY(arm_copy_from_user) #ifdef CONFIG_CPU_SPECTRE get_thread_info r3 ldr r3, [r3, #TI_ADDR_LIMIT] - adds ip, r1, r2 @ ip=addr+size - sub r3, r3, #1 @ addr_limit - 1 - cmpcc ip, r3 @ if (addr+size > addr_limit - 1) - movcs r1, #0 @ addr = NULL - csdb + uaccess_mask_range_ptr r1, r2, r3, ip #endif #include "copy_template.S"
Greg Kroah-Hartman
maintainerPATCH 66/75 ARM: 8810/1: vfp: Fix wrong assignement to ufp_exc
In reply to Greg Kroah-HartmanFrom: Julien Thierry <[email protected]>
Commit 5df7a99bdd0de4a0480320264c44c04543c29d5a upstream.
In vfp_preserve_user_clear_hwstate, ufp_exc->fpinst2 gets assigned to itself. It should actually be hwstate->fpinst2 that gets assigned to the ufp_exc field.
Fixes commit 3aa2df6ec2ca6bc143a65351cca4266d03a8bc41 ("ARM: 8791/1:
vfp: use __copy_to_user() when saving VFP state").
--- arch/arm/vfp/vfpmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/vfp/vfpmodule.c +1 -1
@@ -583,7 +583,7 @@ int vfp_preserve_user_clear_hwstate(stru*/ ufp_exc->fpexc = hwstate->fpexc; ufp_exc->fpinst = hwstate->fpinst; - ufp_exc->fpinst2 = ufp_exc->fpinst2; + ufp_exc->fpinst2 = hwstate->fpinst2;/* Ensure that VFP is disabled. */ vfp_flush_hwstate (thread);
Greg Kroah-Hartman
maintainerPATCH 67/75 ARM: make lookup_processor_type() non-__init
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
Commit 899a42f836678a595f7d2bc36a5a0c2b03d08cbc upstream.
Move lookup_processor_type() out of the __init section so it is callable from (eg) the secondary startup code during hotplug.
--- arch/arm/kernel/head-common.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/arm/kernel/head-common.S +3 -3
@@ -122,6 +122,9 @@ __mmap_switched_data: .long init_thread_union + THREAD_START_SP @ sp .size __mmap_switched_data, . - __mmap_switched_data + __FINIT + .text + /* * This provides a C-API version of __lookup_processor_type */
@@ -133,9 +136,6 @@ ENTRY(lookup_processor_type) ldmfd sp!, {r4 - r6, r9, pc} ENDPROC(lookup_processor_type) - __FINIT - .text - /* * Read processor ID register (CP#15, CR0), and look up in the linker-built * supported processor list. Note that we can't use the absolute addresses
Greg Kroah-Hartman
maintainerPATCH 68/75 ARM: split out processor lookup
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
Commit 65987a8553061515b5851b472081aedb9837a391 upstream.
Split out the lookup of the processor type and associated error handling from the rest of setup_processor() - we will need to use this in the secondary CPU bringup path for big.Little Spectre variant 2 mitigation.
--- arch/arm/include/asm/cputype.h | 1 + arch/arm/kernel/setup.c | 31 +++++++++++++++++++------------ 2 files changed, 20 insertions(+), 12 deletions(-)
arch/arm/include/asm/cputype.h +1 -0
@@ -93,6 +93,7 @@#define ARM_CPU_PART_SCORPION 0x510002d0extern unsigned int processor_id; +struct proc_info_list *lookup_processor (u32 midr);#ifdef CONFIG_CPU_CP15 #define read_cpuid (reg) \
arch/arm/kernel/setup.c +19 -12
@@ -599,22 +599,29 @@ static void __init smp_build_mpidr_hash( }#endif -static void __init setup_processor (void ) +/* +* locate processor in the list of supported processor types. The linker +* builds this table for us from the entries in arch/arm/mm/proc-*.S +*/ +struct proc_info_list *lookup_processor (u32 midr) { -struct proc_info_list *list; +struct proc_info_list *list =lookup_processor_type (midr); -/* -* locate processor in the list of supported processor -* types. The linker builds this table for us from the -* entries in arch/arm/mm/proc-*.S -*/ - list =lookup_processor_type (read_cpuid_id ());if (!list) { -pr_err ("CPU configuration botched (ID %08x), unable to continue.\n" , -read_cpuid_id ()); -while (1 ); +pr_err ("CPU%u: configuration botched (ID %08x), CPU halted\n" , +smp_processor_id (), midr); +while (1 ) +/* can't use cpu_relax() here as it may require MMU setup */ ; } +return list; +} + +static void __init setup_processor (void ) +{ +unsigned int midr =read_cpuid_id (); +struct proc_info_list *list =lookup_processor (midr); + cpu_name = list->cpu_name; __cpu_architecture =__get_cpu_architecture ();
@@ -632,7 +639,7 @@ static void __init setup_processor(void)#endif pr_info ("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n" , - cpu_name,read_cpuid_id (),read_cpuid_id () &15 , + list->cpu_name, midr, midr &15 , proc_arch[cpu_architecture ()],get_cr ()); snprintf(init_utsname()->machine, __NEW_UTS_LEN + 1, "%s%c",
Greg Kroah-Hartman
maintainerPATCH 69/75 ARM: clean up per-processor check_bugs method call
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
Commit 945aceb1db8885d3a35790cf2e810f681db52756 upstream.
Call the per-processor type check_bugs() method in the same way as we do other per-processor functions - move the "processor." detail into proc-fns.h.
--- arch/arm/include/asm/proc-fns.h | 1 + arch/arm/kernel/bugs.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-)
arch/arm/include/asm/proc-fns.h +1 -0
@@ -99,6 +99,7 @@ extern void cpu_do_suspend(void *);extern void cpu_do_resume (void *);#else #define cpu_proc_init processor._proc_init +#define cpu_check_bugs processor.check_bugs#define cpu_proc_fin processor._proc_fin#define cpu_reset processor.reset#define cpu_do_idle processor._do_idle
arch/arm/kernel/bugs.c +2 -2
@@ -6,8 +6,8 @@void check_other_bugs (void ) {#ifdef MULTI_CPU -if (processor.check_bugs) - processor.check_bugs (); +if (cpu_check_bugs) +cpu_check_bugs ();#endif }
Greg Kroah-Hartman
maintainerPATCH 70/75 ARM: add PROC_VTABLE and PROC_TABLE macros
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
Commit e209950fdd065d2cc46e6338e47e52841b830cba upstream.
Allow the way we access members of the processor vtable to be changed at compile time. We will need to move to per-CPU vtables to fix the Spectre variant 2 issues on big.Little systems.
However, we have a couple of calls that do not need the vtable treatment, and indeed cause a kernel warning due to the (later) use of smp_processor_id(), so also introduce the PROC_TABLE macro for these which always use CPU 0's function pointers.
--- arch/arm/include/asm/proc-fns.h | 39 ++++++++++++++++++++++++++------------- arch/arm/kernel/setup.c | 4 +--- 2 files changed, 27 insertions(+), 16 deletions(-)
arch/arm/include/asm/proc-fns.h +26 -13
@@ -23,7 +23,7 @@ struct mm_struct;/* * Don't change this structure - ASM code relies on it. */ -extern struct processor { +struct processor {/* MISC * get data abort address/flags */
@@ -79,9 +79,13 @@ extern struct processor {unsigned int suspend_size;void (*do_suspend)(void *);void (*do_resume)(void *); -} processor; +};#ifndef MULTI_CPU +static inline void init_proc_vtable (const struct processor *p) +{ +} +extern void cpu_proc_init (void );extern void cpu_proc_fin (void );extern int cpu_do_idle (void );
@@ -98,18 +102,27 @@ extern void cpu_reset(unsigned long addrextern void cpu_do_suspend (void *);extern void cpu_do_resume (void *);#else -#define cpu_proc_init processor._proc_init -#define cpu_check_bugs processor.check_bugs -#define cpu_proc_fin processor._proc_fin -#define cpu_reset processor.reset -#define cpu_do_idle processor._do_idle -#define cpu_dcache_clean_area processor.dcache_clean_area -#define cpu_set_pte_ext processor.set_pte_ext -#define cpu_do_switch_mm processor.switch_mm -/* These three are private to arch/arm/kernel/suspend.c */ -#define cpu_do_suspend processor.do_suspend -#define cpu_do_resume processor.do_resume +extern struct processor processor; +#define PROC_VTABLE (f) processor.f +#define PROC_TABLE (f) processor.f +static inline void init_proc_vtable (const struct processor *p) +{ + processor = *p; +} + +#define cpu_proc_init PROC_VTABLE(_proc_init) +#define cpu_check_bugs PROC_VTABLE(check_bugs) +#define cpu_proc_fin PROC_VTABLE(_proc_fin) +#define cpu_reset PROC_VTABLE(reset) +#define cpu_do_idle PROC_VTABLE(_do_idle) +#define cpu_dcache_clean_area PROC_TABLE(dcache_clean_area) +#define cpu_set_pte_ext PROC_TABLE(set_pte_ext) +#define cpu_do_switch_mm PROC_VTABLE(switch_mm) + +/* These two are private to arch/arm/kernel/suspend.c */ +#define cpu_do_suspend PROC_VTABLE(do_suspend) +#define cpu_do_resume PROC_VTABLE(do_resume)#endif extern void cpu_resume (void );
arch/arm/kernel/setup.c +1 -3
@@ -625,9 +625,7 @@ static void __init setup_processor(void) cpu_name = list->cpu_name; __cpu_architecture =__get_cpu_architecture (); -#ifdef MULTI_CPU - processor = *list->proc; -#endif +init_proc_vtable (list->proc);#ifdef MULTI_TLB cpu_tlb = *list->tlb;#endif
Greg Kroah-Hartman
maintainerPATCH 71/75 ARM: spectre-v2: per-CPU vtables to work around big.Little systems
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
Commit 383fb3ee8024d596f488d2dbaf45e572897acbdb upstream.
In big.Little systems, some CPUs require the Spectre workarounds in paths such as the context switch, but other CPUs do not. In order to handle these differences, we need per-CPU vtables.
We are unable to use the kernel's per-CPU variables to support this as per-CPU is not initialised at times when we need access to the vtables, so we have to use an array indexed by logical CPU number.
We use an array-of-pointers to avoid having function pointers in the kernel's read/write .data section.
Note: Added include of linux/slab.h in arch/arm/smp.c.
--- arch/arm/include/asm/proc-fns.h | 23 +++++++++++++++++++++++ arch/arm/kernel/setup.c | 5 +++++ arch/arm/kernel/smp.c | 32 ++++++++++++++++++++++++++++++++ arch/arm/mm/proc-v7-bugs.c | 17 ++--------------- 4 files changed, 62 insertions(+), 15 deletions(-)
arch/arm/include/asm/proc-fns.h +23 -0
@@ -104,12 +104,35 @@ extern void cpu_do_resume(void *);#else extern struct processor processor; +#if defined(CONFIG_BIG_LITTLE ) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR ) +#include <linux/smp.h> +/* +* This can't be a per-cpu variable because we need to access it before +* per-cpu has been initialised. We have a couple of functions that are +* called in a pre-emptible context, and so can't use smp_processor_id() +* there, hence PROC_TABLE(). We insist in init_proc_vtable() that the +* function pointers for these are identical across all CPUs. +*/ +extern struct processor *cpu_vtable[]; +#define PROC_VTABLE (f) cpu_vtable[smp_processor_id()]->f +#define PROC_TABLE (f) cpu_vtable[0]->f +static inline void init_proc_vtable (const struct processor *p) +{ +unsigned int cpu =smp_processor_id (); + *cpu_vtable[cpu] = *p; +WARN_ON_ONCE (cpu_vtable[cpu]->dcache_clean_area != + cpu_vtable[0 ]->dcache_clean_area); +WARN_ON_ONCE (cpu_vtable[cpu]->set_pte_ext != + cpu_vtable[0 ]->set_pte_ext); +} +#else #define PROC_VTABLE (f) processor.f#define PROC_TABLE (f) processor.fstatic inline void init_proc_vtable (const struct processor *p) { processor = *p; } +#endif #define cpu_proc_init PROC_VTABLE(_proc_init)#define cpu_check_bugs PROC_VTABLE(check_bugs)
arch/arm/kernel/setup.c +5 -0
@@ -113,6 +113,11 @@ EXPORT_SYMBOL(elf_hwcap2);#ifdef MULTI_CPU struct processor processor__read_mostly ; +#if defined(CONFIG_BIG_LITTLE ) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR ) +struct processor *cpu_vtable[NR_CPUS ] = { + [0 ] = &processor, +}; +#endif #endif #ifdef MULTI_TLB struct cpu_tlb_fns cpu_tlb__read_mostly ;
arch/arm/kernel/smp.c +32 -0
@@ -27,6 +27,7 @@#include <linux/completion.h> #include <linux/cpufreq.h> #include <linux/irq_work.h> +#include <linux/slab.h> #include <linux/atomic.h> #include <asm/bugs.h>
@@ -40,6 +41,7 @@#include <asm/mmu_context.h> #include <asm/pgtable.h> #include <asm/pgalloc.h> +#include <asm/procinfo.h> #include <asm/processor.h> #include <asm/sections.h> #include <asm/tlbflush.h>
@@ -96,6 +98,30 @@ static unsigned long get_arch_pgd(pgd_t#endif } +#if defined(CONFIG_BIG_LITTLE ) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR ) +static int secondary_biglittle_prepare (unsigned int cpu) +{ +if (!cpu_vtable[cpu]) + cpu_vtable[cpu] =kzalloc (sizeof (*cpu_vtable[cpu]),GFP_KERNEL ); + +return cpu_vtable[cpu] ?0 : -ENOMEM ; +} + +static void secondary_biglittle_init (void ) +{ +init_proc_vtable (lookup_processor (read_cpuid_id ())->proc); +} +#else +static int secondary_biglittle_prepare (unsigned int cpu) +{ +return 0 ; +} + +static void secondary_biglittle_init (void ) +{ +} +#endif +int __cpu_up (unsigned int cpu,struct task_struct *idle) {int ret;
@@ -103,6 +129,10 @@ int __cpu_up(unsigned int cpu, struct taif (!smp_ops.smp_boot_secondary)return -ENOSYS ; + ret =secondary_biglittle_prepare (cpu); +if (ret) +return ret; +/* * We need to tell the secondary core where to find * its stack and the page tables.
@@ -354,6 +384,8 @@ asmlinkage void secondary_start_kernel(vstruct mm_struct *mm = &init_mm;unsigned int cpu; +secondary_biglittle_init (); +/* * The identity mapping is uncached (strongly ordered), so * switch away from it before attempting any exclusive accesses.
arch/arm/mm/proc-v7-bugs.c +2 -15
@@ -52,8 +52,6 @@ static void cpu_v7_spectre_init(void)case ARM_CPU_PART_CORTEX_A17 :case ARM_CPU_PART_CORTEX_A73 :case ARM_CPU_PART_CORTEX_A75 : -if (processor.switch_mm != cpu_v7_bpiall_switch_mm) - goto bl_error;per_cpu (harden_branch_predictor_fn, cpu) = harden_branch_predictor_bpiall; spectre_v2_method ="BPIALL" ;
@@ -61,8 +59,6 @@ static void cpu_v7_spectre_init(void)case ARM_CPU_PART_CORTEX_A15 :case ARM_CPU_PART_BRAHMA_B15 : -if (processor.switch_mm != cpu_v7_iciallu_switch_mm) - goto bl_error;per_cpu (harden_branch_predictor_fn, cpu) = harden_branch_predictor_iciallu; spectre_v2_method ="ICIALLU" ;
@@ -88,11 +84,9 @@ static void cpu_v7_spectre_init(void) ARM_SMCCC_ARCH_WORKAROUND_1, &res);if ((int )res.a0 !=0 )break ; -if (processor.switch_mm != cpu_v7_hvc_switch_mm && cpu) - goto bl_error;per_cpu (harden_branch_predictor_fn, cpu) = call_hvc_arch_workaround_1; - processor.switch_mm = cpu_v7_hvc_switch_mm; + cpu_do_switch_mm = cpu_v7_hvc_switch_mm; spectre_v2_method ="hypervisor" ;break ;
@@ -101,11 +95,9 @@ static void cpu_v7_spectre_init(void) ARM_SMCCC_ARCH_WORKAROUND_1, &res);if ((int )res.a0 !=0 )break ; -if (processor.switch_mm != cpu_v7_smc_switch_mm && cpu) - goto bl_error;per_cpu (harden_branch_predictor_fn, cpu) = call_smc_arch_workaround_1; - processor.switch_mm = cpu_v7_smc_switch_mm; + cpu_do_switch_mm = cpu_v7_smc_switch_mm; spectre_v2_method ="firmware" ;break ;
@@ -119,11 +111,6 @@ static void cpu_v7_spectre_init(void)if (spectre_v2_method)pr_info ("CPU%u: Spectre v2: using %s workaround\n" , smp_processor_id(), spectre_v2_method); -return ; - -bl_error: -pr_err ("CPU%u: Spectre v2: incorrect context switching function, system vulnerable\n" , - cpu); }#else static void cpu_v7_spectre_init (void )
Greg Kroah-Hartman
maintainerPATCH 72/75 ARM: ensure that processor vtables is not lost after boot
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
Commit 3a4d0c2172bcf15b7a3d9d498b2b355f9864286b upstream.
Marek Szyprowski reported problems with CPU hotplug in current kernels. This was tracked down to the processor vtables being located in an init section, and therefore discarded after kernel boot, despite being required after boot to properly initialise the non-boot CPUs.
Arrange for these tables to end up in .rodata when required.
--- arch/arm/mm/proc-macros.S | 10 ++++++++++ 1 file changed, 10 insertions(+)
arch/arm/mm/proc-macros.S +10 -0
@@ -259,6 +259,13 @@ .endm .macro define_processor_functions name:req, dabort:req, pabort:req, nommu=0, suspend=0, bugs=0 +/* + * If we are building for big.Little with branch predictor hardening, + * we need the processor function tables to remain available after boot. + */ +#if 1 // defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR) + .section ".rodata" +#endif .type \name\()_processor_functions, #object .align 2 ENTRY(\name\()_processor_functions)
@@ -294,6 +301,9 @@ ENTRY(\name\()_processor_functions) .endif .size \name\()_processor_functions, . - \name\()_processor_functions +#if 1 // defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR) + .previous +#endif .endm .macro define_cache_functions name:req
Greg Kroah-Hartman
maintainerPATCH 73/75 ARM: fix the cockup in the previous patch
In reply to Greg Kroah-HartmanFrom: Russell King <[email protected]>
Commit d6951f582cc50ba0ad22ef46b599740966599b14 upstream.
The intention in the previous patch was to only place the processor tables in the .rodata section if big.Little was being built and we wanted the branch target hardening, but instead (due to the way it was tested) it ended up always placing the tables into the .rodata section.
Although harmless, let's correct this anyway.
--- arch/arm/mm/proc-macros.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm/mm/proc-macros.S +2 -2
@@ -263,7 +263,7 @@ * If we are building for big.Little with branch predictor hardening, * we need the processor function tables to remain available after boot. */ -#if 1 // defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR) +#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR) .section ".rodata" #endif .type \name\()_processor_functions, #object
@@ -301,7 +301,7 @@ ENTRY(\name\()_processor_functions) .endif .size \name\()_processor_functions, . - \name\()_processor_functions -#if 1 // defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR) +#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR) .previous #endif .endm
Greg Kroah-Hartman
maintainerPATCH 74/75 alarmtimer: Change remaining ENOTSUPP to EOPNOTSUPP
In reply to Greg Kroah-HartmanFrom: Petr Vorel <[email protected]>
Fix backport of commit f18ddc13af981ce3c7b7f26925f099e7c6929aba upstream.
Update backport to change ENOTSUPP to EOPNOTSUPP in alarm_timer_{del,set}(), which were removed in f2c45807d3992fe0f173f34af9c347d907c31686 in v4.13-rc1.
--- kernel/time/alarmtimer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/time/alarmtimer.c +2 -2
@@ -573,7 +573,7 @@ static void alarm_timer_get(struct k_itistatic int alarm_timer_del (struct k_itimer *timr) {if (!rtcdev) -return -ENOTSUPP ; +return -EOPNOTSUPP ;if (alarm_try_to_cancel (&timr->it.alarm.alarmtimer) <0 )return TIMER_RETRY ;
@@ -597,7 +597,7 @@ static int alarm_timer_set(struct k_itimktime_t exp;if (!rtcdev) -return -ENOTSUPP ; +return -EOPNOTSUPP ;if (flags & ~TIMER_ABSTIME )return -EINVAL ;
Greg Kroah-Hartman
maintainerPATCH 75/75 fs/dcache: move security_d_instantiate() behind attaching dentry to inode
In reply to Greg Kroah-HartmanFrom: "zhangyi (F)" <[email protected]>
During backport 1e2e547a93a "do d_instantiate/unlock_new_inode combinations safely", there was a error instantiating sequence of attaching dentry to inode and calling security_d_instantiate().
Before commit ce23e640133 "->getxattr(): pass dentry and inode as separate arguments" and b96809173e9 "security_d_instantiate(): move to the point prior to attaching dentry to inode", security_d_instantiate() should be called beind __d_instantiate(), otherwise it will trigger below problem when CONFIG_SECURITY_SMACK on ext4 was enabled because d_inode(dentry) used by ->getxattr() is NULL before __d_instantiate() instantiate inode.
[ 31.858026] BUG: unable to handle kernel paging request at ffffffffffffff70 ... [ 31.882024] Call Trace: [ 31.882378] [<ffffffffa347f75c>] ext4_xattr_get+0x8c/0x3e0 [ 31.883195] [<ffffffffa3489454>] ext4_xattr_security_get+0x24/0x40 [ 31.884086] [<ffffffffa336a56b>] generic_getxattr+0x5b/0x90 [ 31.884907] [<ffffffffa3700514>] smk_fetch+0xb4/0x150 [ 31.885634] [<ffffffffa3700772>] smack_d_instantiate+0x1c2/0x550 [ 31.886508] [<ffffffffa36f9a5a>] security_d_instantiate+0x3a/0x80 [ 31.887389] [<ffffffffa3353b26>] d_instantiate_new+0x36/0x130 [ 31.888223] [<ffffffffa342b1ef>] ext4_mkdir+0x4af/0x6a0 [ 31.888928] [<ffffffffa3343470>] vfs_mkdir+0x100/0x280 [ 31.889536] [<ffffffffa334b086>] SyS_mkdir+0xb6/0x170 [ 31.890255] [<ffffffffa307c855>] ? trace_do_page_fault+0x95/0x2b0 [ 31.891134] [<ffffffffa3c5e078>] entry_SYSCALL_64_fastpath+0x18/0x73
--- fs/dcache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/dcache.c +1 -1
@@ -1903,7 +1903,6 @@ void d_instantiate_new(struct dentry *enBUG_ON (!hlist_unhashed (&entry->d_u.d_alias));BUG_ON (!inode);lockdep_annotate_inode_mutex_key (inode); -security_d_instantiate (entry, inode);spin_lock (&inode->i_lock);__d_instantiate (entry, inode);WARN_ON (!(inode->i_state &I_NEW ));
@@ -1911,6 +1910,7 @@ void d_instantiate_new(struct dentry *ensmp_mb ();wake_up_bit (&inode->i_state, __I_NEW);spin_unlock (&inode->i_lock); +security_d_instantiate (entry, inode); }EXPORT_SYMBOL (d_instantiate_new);
stable-rc/linux-4.4.y boot: 80 boots: 0 failed, 72 passed with 7 offline, 1 conflict (v4.4.199-76-g6afbf4832d8a)
stable-rc/linux-4.4.y boot: 80 boots: 0 failed, 72 passed with 7 offline, 1 conflict (v4.4.199-76-g6afbf4832d8a)
Full Boot Summary: https://kernelci.org/boot/all/job/stable-rc/branch/linux-4.4.y/kernel/v4.4.199-76-g6afbf4832d8a/
Full Build Summary: https://kernelci.org/build/stable-rc/branch/linux-4.4.y/kernel/v4.4.199-76-g6afbf4832d8a/
Tree: stable-rc
Branch: linux-4.4.y
Git Describe: v4.4.199-76-g6afbf4832d8a
Git Commit: 6afbf4832d8a30149fdb36136e222f795f2e9ec9
Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
Tested: 41 unique boards, 17 SoC families, 13 builds out of 190
Offline Platforms:
arm:
sunxi_defconfig:
gcc-8
sun5i-r8-chip: 1 offline lab
sun7i-a20-bananapi: 1 offline lab
multi_v7_defconfig:
gcc-8
qcom-apq8064-cm-qs600: 1 offline lab
sun5i-r8-chip: 1 offline lab
sun7i-a20-bananapi: 1 offline lab
davinci_all_defconfig:
gcc-8
dm365evm,legacy: 1 offline lab
qcom_defconfig:
gcc-8
qcom-apq8064-cm-qs600: 1 offline labConflicting Boot Failure Detected: (These likely are not failures as other labs are reporting PASS. Needs review.)
i386:
i386_defconfig:
qemu_i386:
lab-collabora: PASS (gcc-8)
lab-baylibre: FAIL (gcc-8)
---
For more info write to <[email protected]>
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.4.200 release. There are 75 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun 10 Nov 2019 05:42:11 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.200-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.4.y
and the diffstat can be found below.thanks,
greg k-h
Results from Linaro’s test farm.
No regressions on arm64, arm, x86_64, and i386.
Summary
------------------------------------------------------------------------
kernel: 4.4.200-rc1
git repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
git branch: linux-4.4.y
git commit: 6afbf4832d8a30149fdb36136e222f795f2e9ec9
git describe: v4.4.199-76-g6afbf4832d8a
Test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-4.4-oe/build/v4.4.199-76-g6afbf4832d8a
No regressions (compared to build v4.4.199)
No fixes (compared to build v4.4.199)
Ran 16997 total tests in the following environments and test suites.
Environments
--------------
- i386
- juno-r2 - arm64
- qemu_arm
- qemu_arm64
- qemu_i386
- qemu_x86_64
- x15 - arm
- x86_64
Test Suites
-----------
* build
* kselftest
* libhugetlbfs
* ltp-cap_bounds-tests
* ltp-commands-tests
* ltp-cpuhotplug-tests
* ltp-dio-tests
* ltp-fcntl-locktests-tests
* ltp-filecaps-tests
* ltp-fs-tests
* ltp-fs_bind-tests
* ltp-fs_perms_simple-tests
* ltp-fsx-tests
* ltp-hugetlb-tests
* ltp-io-tests
* ltp-ipc-tests
* ltp-math-tests
* ltp-mm-tests
* ltp-nptl-tests
* ltp-pty-tests
* ltp-sched-tests
* ltp-securebits-tests
* ltp-syscalls-tests
* network-basic-tests
* perf
* prep-tmp-disk
* kvm-unit-tests
* ltp-containers-tests
* ltp-cve-tests
* ltp-open-posix-tests
* spectre-meltdown-checker-test
* v4l2-compliance
* install-android-platform-tools-r2600
* kselftest-vsyscall-mode-native
* kselftest-vsyscall-mode-none
* ssuite
Signature · 2 lines
Linaro LKFT https://lkft.linaro.org
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.4.200 release. There are 75 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun 10 Nov 2019 05:42:11 PM UTC. Anything received after that time might be too late.
Build results:
total: 170 pass: 170 fail: 0 Qemu test results: total: 324 pass: 324 fail: 0
Guenter