From: Zhou Yanjie zhouyanjie@zoho.com
[ Upstream commit 053951dda71ecb4b554a2cdbe26f5f6f9bee9dd2 ]
In order to further reduce power consumption, the XBurst core by default attempts to avoid branch target buffer lookups by detecting & special casing loops. This feature will cause BogoMIPS and lpj calculate in error. Set cp0 config7 bit 4 to disable this feature.
Signed-off-by: Zhou Yanjie zhouyanjie@zoho.com Signed-off-by: Paul Burton paul.burton@mips.com Cc: linux-mips@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: ralf@linux-mips.org Cc: paul@crapouillou.net Cc: jhogan@kernel.org Cc: malat@debian.org Cc: gregkh@linuxfoundation.org Cc: tglx@linutronix.de Cc: allison@lohutok.net Cc: syq@debian.org Cc: chenhc@lemote.com Cc: jiaxun.yang@flygoat.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/include/asm/mipsregs.h | 4 ++++ arch/mips/kernel/cpu-probe.c | 7 +++++++ 2 files changed, 11 insertions(+)
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 1e6966e8527e9..bdbdc19a2b8f8 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -689,6 +689,9 @@ #define MIPS_CONF7_IAR (_ULCAST_(1) << 10) #define MIPS_CONF7_AR (_ULCAST_(1) << 16)
+/* Ingenic Config7 bits */ +#define MIPS_CONF7_BTB_LOOP_EN (_ULCAST_(1) << 4) + /* Config7 Bits specific to MIPS Technologies. */
/* Performance counters implemented Per TC */ @@ -2813,6 +2816,7 @@ __BUILD_SET_C0(status) __BUILD_SET_C0(cause) __BUILD_SET_C0(config) __BUILD_SET_C0(config5) +__BUILD_SET_C0(config7) __BUILD_SET_C0(intcontrol) __BUILD_SET_C0(intctl) __BUILD_SET_C0(srsmap) diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 9635c1db3ae6a..e654ffc1c8a0d 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -1964,6 +1964,13 @@ static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu) c->cputype = CPU_JZRISC; c->writecombine = _CACHE_UNCACHED_ACCELERATED; __cpu_name[cpu] = "Ingenic JZRISC"; + /* + * The XBurst core by default attempts to avoid branch target + * buffer lookups by detecting & special casing loops. This + * feature will cause BogoMIPS and lpj calculate in error. + * Set cp0 config7 bit 4 to disable this feature. + */ + set_c0_config7(MIPS_CONF7_BTB_LOOP_EN); break; default: panic("Unknown Ingenic Processor ID!");
From: Paul Cercueil paul@crapouillou.net
[ Upstream commit 73dd11dc1a883d4c994d729dc9984f4890001157 ]
Add the missing TCU clock to the list of clocks supplied by the CGU for the JZ4740 SoC.
Signed-off-by: Paul Cercueil paul@crapouillou.net Tested-by: Mathieu Malaterre malat@debian.org Tested-by: Artur Rojek contact@artur-rojek.eu Acked-by: Stephen Boyd sboyd@kernel.org Acked-by: Rob Herring robh@kernel.org Signed-off-by: Paul Burton paul.burton@mips.com Cc: Ralf Baechle ralf@linux-mips.org Cc: James Hogan jhogan@kernel.org Cc: Jonathan Corbet corbet@lwn.net Cc: Lee Jones lee.jones@linaro.org Cc: Arnd Bergmann arnd@arndb.de Cc: Daniel Lezcano daniel.lezcano@linaro.org Cc: Thomas Gleixner tglx@linutronix.de Cc: Michael Turquette mturquette@baylibre.com Cc: Jason Cooper jason@lakedaemon.net Cc: Marc Zyngier marc.zyngier@arm.com Cc: Rob Herring robh+dt@kernel.org Cc: Mark Rutland mark.rutland@arm.com Cc: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: linux-doc@vger.kernel.org Cc: linux-mips@vger.kernel.org Cc: linux-clk@vger.kernel.org Cc: od@zcrc.me Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/ingenic/jz4740-cgu.c | 6 ++++++ include/dt-bindings/clock/jz4740-cgu.h | 1 + 2 files changed, 7 insertions(+)
diff --git a/drivers/clk/ingenic/jz4740-cgu.c b/drivers/clk/ingenic/jz4740-cgu.c index 4c0a20949c2c2..67f8a0e142845 100644 --- a/drivers/clk/ingenic/jz4740-cgu.c +++ b/drivers/clk/ingenic/jz4740-cgu.c @@ -222,6 +222,12 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = { .parents = { JZ4740_CLK_EXT, -1, -1, -1 }, .gate = { CGU_REG_CLKGR, 5 }, }, + + [JZ4740_CLK_TCU] = { + "tcu", CGU_CLK_GATE, + .parents = { JZ4740_CLK_EXT, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR, 1 }, + }, };
static void __init jz4740_cgu_init(struct device_node *np) diff --git a/include/dt-bindings/clock/jz4740-cgu.h b/include/dt-bindings/clock/jz4740-cgu.h index 6ed83f926ae71..e82d77028581a 100644 --- a/include/dt-bindings/clock/jz4740-cgu.h +++ b/include/dt-bindings/clock/jz4740-cgu.h @@ -34,5 +34,6 @@ #define JZ4740_CLK_ADC 19 #define JZ4740_CLK_I2C 20 #define JZ4740_CLK_AIC 21 +#define JZ4740_CLK_TCU 22
#endif /* __DT_BINDINGS_CLOCK_JZ4740_CGU_H__ */
From: Nathan Chancellor natechancellor@gmail.com
[ Upstream commit c2869aafe7191d366d74c55cb8a93c6d0baba317 ]
clang warns:
arch/mips/kernel/branch.c:148:8: error: variable 'bc_false' is used uninitialized whenever switch case is taken [-Werror,-Wsometimes-uninitialized] case mm_bc2t_op: ^~~~~~~~~~ arch/mips/kernel/branch.c:157:8: note: uninitialized use occurs here if (bc_false) ^~~~~~~~ arch/mips/kernel/branch.c:149:8: error: variable 'bc_false' is used uninitialized whenever switch case is taken [-Werror,-Wsometimes-uninitialized] case mm_bc1t_op: ^~~~~~~~~~ arch/mips/kernel/branch.c:157:8: note: uninitialized use occurs here if (bc_false) ^~~~~~~~ arch/mips/kernel/branch.c:142:4: note: variable 'bc_false' is declared here int bc_false = 0; ^ 2 errors generated.
When mm_bc1t_op and mm_bc2t_op are taken, the bc_false initialization does not happen, which leads to a garbage value upon use, as illustrated below with a small sample program.
$ mipsel-linux-gnu-gcc --version | head -n1 mipsel-linux-gnu-gcc (Debian 8.3.0-2) 8.3.0
$ clang --version | head -n1 ClangBuiltLinux clang version 9.0.0 (git://github.com/llvm/llvm-project 544315b4197034a3be8acd12cba56a75fb1f08dc) (based on LLVM 9.0.0svn)
$ cat test.c #include <stdio.h>
static void switch_scoped(int opcode) { switch (opcode) { case 1: case 2: { int bc_false = 0;
bc_false = 4; case 3: case 4: printf("\t* switch scoped bc_false = %d\n", bc_false); } } }
static void function_scoped(int opcode) { int bc_false = 0;
switch (opcode) { case 1: case 2: { bc_false = 4; case 3: case 4: printf("\t* function scoped bc_false = %d\n", bc_false); } } }
int main(void) { int opcode;
for (opcode = 1; opcode < 5; opcode++) { printf("opcode = %d:\n", opcode); switch_scoped(opcode); function_scoped(opcode); printf("\n"); }
return 0; }
$ mipsel-linux-gnu-gcc -std=gnu89 -static test.c && \ qemu-mipsel a.out opcode = 1: * switch scoped bc_false = 4 * function scoped bc_false = 4
opcode = 2: * switch scoped bc_false = 4 * function scoped bc_false = 4
opcode = 3: * switch scoped bc_false = 2147483004 * function scoped bc_false = 0
opcode = 4: * switch scoped bc_false = 2147483004 * function scoped bc_false = 0
$ clang -std=gnu89 --target=mipsel-linux-gnu -m32 -static test.c && \ qemu-mipsel a.out opcode = 1: * switch scoped bc_false = 4 * function scoped bc_false = 4
opcode = 2: * switch scoped bc_false = 4 * function scoped bc_false = 4
opcode = 3: * switch scoped bc_false = 2147483004 * function scoped bc_false = 0
opcode = 4: * switch scoped bc_false = 2147483004 * function scoped bc_false = 0
Move the definition up so that we get the right behavior and mark it __maybe_unused as it will not be used when CONFIG_MIPS_FP_SUPPORT isn't enabled.
Fixes: 6a1cc218b9cc ("MIPS: branch: Remove FP branch handling when CONFIG_MIPS_FP_SUPPORT=n") Link: https://github.com/ClangBuiltLinux/linux/issues/603 Signed-off-by: Nathan Chancellor natechancellor@gmail.com Signed-off-by: Paul Burton paul.burton@mips.com Cc: Ralf Baechle ralf@linux-mips.org Cc: James Hogan jhogan@kernel.org Cc: Nick Desaulniers ndesaulniers@google.com Cc: linux-mips@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: clang-built-linux@googlegroups.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/kernel/branch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c index 1db29957a9318..2c38f75d87ffb 100644 --- a/arch/mips/kernel/branch.c +++ b/arch/mips/kernel/branch.c @@ -58,6 +58,7 @@ int __mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, unsigned long *contpc) { union mips_instruction insn = (union mips_instruction)dec_insn.insn; + int __maybe_unused bc_false = 0;
if (!cpu_has_mmips) return 0; @@ -139,7 +140,6 @@ int __mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, #ifdef CONFIG_MIPS_FP_SUPPORT case mm_bc2f_op: case mm_bc1f_op: { - int bc_false = 0; unsigned int fcr31; unsigned int bit;
From: Nathan Chancellor natechancellor@gmail.com
[ Upstream commit c59ae0a1055127dd3828a88e111a0db59b254104 ]
clang warns:
arch/mips/mm/tlbex.c:634:19: error: use of logical '&&' with constant operand [-Werror,-Wconstant-logical-operand] if (cpu_has_rixi && _PAGE_NO_EXEC) { ^ ~~~~~~~~~~~~~ arch/mips/mm/tlbex.c:634:19: note: use '&' for a bitwise operation if (cpu_has_rixi && _PAGE_NO_EXEC) { ^~ & arch/mips/mm/tlbex.c:634:19: note: remove constant to silence this warning if (cpu_has_rixi && _PAGE_NO_EXEC) { ~^~~~~~~~~~~~~~~~ 1 error generated.
Explicitly cast this value to a boolean so that clang understands we intend for this to be a non-zero value.
Fixes: 00bf1c691d08 ("MIPS: tlbex: Avoid placing software PTE bits in Entry* PFN fields") Link: https://github.com/ClangBuiltLinux/linux/issues/609 Signed-off-by: Nathan Chancellor natechancellor@gmail.com Signed-off-by: Paul Burton paul.burton@mips.com Cc: Ralf Baechle ralf@linux-mips.org Cc: James Hogan jhogan@kernel.org Cc: Nick Desaulniers ndesaulniers@google.com Cc: linux-mips@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: clang-built-linux@googlegroups.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/mm/tlbex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 144ceb0fba88f..bece1264d1c5a 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -631,7 +631,7 @@ static __maybe_unused void build_convert_pte_to_entrylo(u32 **p, return; }
- if (cpu_has_rixi && _PAGE_NO_EXEC) { + if (cpu_has_rixi && !!_PAGE_NO_EXEC) { if (fill_includes_sw_bits) { UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL)); } else {
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit 232219b9a464c2479c98aa589acb1bd3383ae9d6 ]
When the kernel is build with lockdep support and the i2c-cht-wc driver is used, the following warning is shown:
[ 66.674334] ====================================================== [ 66.674337] WARNING: possible circular locking dependency detected [ 66.674340] 5.3.0-rc4+ #83 Not tainted [ 66.674342] ------------------------------------------------------ [ 66.674345] systemd-udevd/1232 is trying to acquire lock: [ 66.674349] 00000000a74dab07 (intel_soc_pmic_chtwc:167:(&cht_wc_regmap_cfg)->lock){+.+.}, at: regmap_write+0x31/0x70 [ 66.674360] but task is already holding lock: [ 66.674362] 00000000d44a85b7 (i2c_register_adapter){+.+.}, at: i2c_smbus_xfer+0x49/0xf0 [ 66.674370] which lock already depends on the new lock.
[ 66.674371] the existing dependency chain (in reverse order) is: [ 66.674374] -> #1 (i2c_register_adapter){+.+.}: [ 66.674381] rt_mutex_lock_nested+0x46/0x60 [ 66.674384] i2c_smbus_xfer+0x49/0xf0 [ 66.674387] i2c_smbus_read_byte_data+0x45/0x70 [ 66.674391] cht_wc_byte_reg_read+0x35/0x50 [ 66.674394] _regmap_read+0x63/0x1a0 [ 66.674396] _regmap_update_bits+0xa8/0xe0 [ 66.674399] regmap_update_bits_base+0x63/0xa0 [ 66.674403] regmap_irq_update_bits.isra.0+0x3b/0x50 [ 66.674406] regmap_add_irq_chip+0x592/0x7a0 [ 66.674409] devm_regmap_add_irq_chip+0x89/0xed [ 66.674412] cht_wc_probe+0x102/0x158 [ 66.674415] i2c_device_probe+0x95/0x250 [ 66.674419] really_probe+0xf3/0x380 [ 66.674422] driver_probe_device+0x59/0xd0 [ 66.674425] device_driver_attach+0x53/0x60 [ 66.674428] __driver_attach+0x92/0x150 [ 66.674431] bus_for_each_dev+0x7d/0xc0 [ 66.674434] bus_add_driver+0x14d/0x1f0 [ 66.674437] driver_register+0x6d/0xb0 [ 66.674440] i2c_register_driver+0x45/0x80 [ 66.674445] do_one_initcall+0x60/0x2f4 [ 66.674450] kernel_init_freeable+0x20d/0x2b4 [ 66.674453] kernel_init+0xa/0x10c [ 66.674457] ret_from_fork+0x3a/0x50 [ 66.674459] -> #0 (intel_soc_pmic_chtwc:167:(&cht_wc_regmap_cfg)->lock){+.+.}: [ 66.674465] __lock_acquire+0xe07/0x1930 [ 66.674468] lock_acquire+0x9d/0x1a0 [ 66.674472] __mutex_lock+0xa8/0x9a0 [ 66.674474] regmap_write+0x31/0x70 [ 66.674480] cht_wc_i2c_adap_smbus_xfer+0x72/0x240 [i2c_cht_wc] [ 66.674483] __i2c_smbus_xfer+0x1a3/0x640 [ 66.674486] i2c_smbus_xfer+0x67/0xf0 [ 66.674489] i2c_smbus_read_byte_data+0x45/0x70 [ 66.674494] bq24190_probe+0x26b/0x410 [bq24190_charger] [ 66.674497] i2c_device_probe+0x189/0x250 [ 66.674500] really_probe+0xf3/0x380 [ 66.674503] driver_probe_device+0x59/0xd0 [ 66.674506] device_driver_attach+0x53/0x60 [ 66.674509] __driver_attach+0x92/0x150 [ 66.674512] bus_for_each_dev+0x7d/0xc0 [ 66.674515] bus_add_driver+0x14d/0x1f0 [ 66.674518] driver_register+0x6d/0xb0 [ 66.674521] i2c_register_driver+0x45/0x80 [ 66.674524] do_one_initcall+0x60/0x2f4 [ 66.674528] do_init_module+0x5c/0x230 [ 66.674531] load_module+0x2707/0x2a20 [ 66.674534] __do_sys_init_module+0x188/0x1b0 [ 66.674537] do_syscall_64+0x5c/0xb0 [ 66.674541] entry_SYSCALL_64_after_hwframe+0x49/0xbe [ 66.674543] other info that might help us debug this:
[ 66.674545] Possible unsafe locking scenario:
[ 66.674547] CPU0 CPU1 [ 66.674548] ---- ---- [ 66.674550] lock(i2c_register_adapter); [ 66.674553] lock(intel_soc_pmic_chtwc:167:(&cht_wc_regmap_cfg)->lock); [ 66.674556] lock(i2c_register_adapter); [ 66.674559] lock(intel_soc_pmic_chtwc:167:(&cht_wc_regmap_cfg)->lock); [ 66.674561] *** DEADLOCK ***
The problem is that the CHT Whiskey Cove PMIC's builtin i2c-adapter is itself a part of an i2c-client (the PMIC). This means that transfers done through it take adapter->bus_lock twice, once for the parent i2c-adapter and once for its own bus_lock. Lockdep does not like this nested locking.
To make lockdep happy in the case of busses with muxes, the i2c-core's i2c_adapter_lock_bus function calls:
rt_mutex_lock_nested(&adapter->bus_lock, i2c_adapter_depth(adapter));
But i2c_adapter_depth only works when the direct parent of the adapter is another adapter, as it is only meant for muxes. In this case there is an i2c-client and MFD instantiated platform_device in the parent->child chain between the 2 devices.
This commit overrides the default i2c_lock_operations, passing a hardcoded depth of 1 to rt_mutex_lock_nested, making lockdep happy.
Note that if there were to be a mux attached to the i2c-wc-cht adapter, this would break things again since the i2c-mux code expects the root-adapter to have a locking depth of 0. But the i2c-wc-cht adapter always has only 1 client directly attached in the form of the charger IC paired with the CHT Whiskey Cove PMIC.
Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Wolfram Sang wsa@the-dreams.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/busses/i2c-cht-wc.c | 46 +++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+)
diff --git a/drivers/i2c/busses/i2c-cht-wc.c b/drivers/i2c/busses/i2c-cht-wc.c index 66af44bfa67d5..f6546de66fbc8 100644 --- a/drivers/i2c/busses/i2c-cht-wc.c +++ b/drivers/i2c/busses/i2c-cht-wc.c @@ -178,6 +178,51 @@ static const struct i2c_algorithm cht_wc_i2c_adap_algo = { .smbus_xfer = cht_wc_i2c_adap_smbus_xfer, };
+/* + * We are an i2c-adapter which itself is part of an i2c-client. This means that + * transfers done through us take adapter->bus_lock twice, once for our parent + * i2c-adapter and once to take our own bus_lock. Lockdep does not like this + * nested locking, to make lockdep happy in the case of busses with muxes, the + * i2c-core's i2c_adapter_lock_bus function calls: + * rt_mutex_lock_nested(&adapter->bus_lock, i2c_adapter_depth(adapter)); + * + * But i2c_adapter_depth only works when the direct parent of the adapter is + * another adapter, as it is only meant for muxes. In our case there is an + * i2c-client and MFD instantiated platform_device in the parent->child chain + * between the 2 devices. + * + * So we override the default i2c_lock_operations and pass a hardcoded + * depth of 1 to rt_mutex_lock_nested, to make lockdep happy. + * + * Note that if there were to be a mux attached to our adapter, this would + * break things again since the i2c-mux code expects the root-adapter to have + * a locking depth of 0. But we always have only 1 client directly attached + * in the form of the Charger IC paired with the CHT Whiskey Cove PMIC. + */ +static void cht_wc_i2c_adap_lock_bus(struct i2c_adapter *adapter, + unsigned int flags) +{ + rt_mutex_lock_nested(&adapter->bus_lock, 1); +} + +static int cht_wc_i2c_adap_trylock_bus(struct i2c_adapter *adapter, + unsigned int flags) +{ + return rt_mutex_trylock(&adapter->bus_lock); +} + +static void cht_wc_i2c_adap_unlock_bus(struct i2c_adapter *adapter, + unsigned int flags) +{ + rt_mutex_unlock(&adapter->bus_lock); +} + +static const struct i2c_lock_operations cht_wc_i2c_adap_lock_ops = { + .lock_bus = cht_wc_i2c_adap_lock_bus, + .trylock_bus = cht_wc_i2c_adap_trylock_bus, + .unlock_bus = cht_wc_i2c_adap_unlock_bus, +}; + /**** irqchip for the client connected to the extchgr i2c adapter ****/ static void cht_wc_i2c_irq_lock(struct irq_data *data) { @@ -286,6 +331,7 @@ static int cht_wc_i2c_adap_i2c_probe(struct platform_device *pdev) adap->adapter.owner = THIS_MODULE; adap->adapter.class = I2C_CLASS_HWMON; adap->adapter.algo = &cht_wc_i2c_adap_algo; + adap->adapter.lock_ops = &cht_wc_i2c_adap_lock_ops; strlcpy(adap->adapter.name, "PMIC I2C Adapter", sizeof(adap->adapter.name)); adap->adapter.dev.parent = &pdev->dev;
From: Kai-Heng Feng kai.heng.feng@canonical.com
[ Upstream commit 76380a607ba0b28627c9b4b55cd47a079a59624b ]
Goodix touchpad may drop its first couple input events when i2c-designware-platdrv and intel-lpss it connects to took too long to runtime resume from runtime suspended state.
This issue happens becuase the touchpad has a rather small buffer to store up to 13 input events, so if the host doesn't read those events in time (i.e. runtime resume takes too long), events are dropped from the touchpad's buffer.
The bottleneck is D3cold delay it waits when transitioning from D3cold to D0, hence remove the delay to make the resume faster. I've tested some systems with intel-lpss and haven't seen any regression.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=202683 Signed-off-by: Kai-Heng Feng kai.heng.feng@canonical.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/intel-lpss-pci.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/mfd/intel-lpss-pci.c b/drivers/mfd/intel-lpss-pci.c index ade6e1ce5a983..e3a04929aaa36 100644 --- a/drivers/mfd/intel-lpss-pci.c +++ b/drivers/mfd/intel-lpss-pci.c @@ -35,6 +35,8 @@ static int intel_lpss_pci_probe(struct pci_dev *pdev, info->mem = &pdev->resource[0]; info->irq = pdev->irq;
+ pdev->d3cold_delay = 0; + /* Probably it is enough to set this for iDMA capable devices only */ pci_set_master(pdev); pci_try_set_mwi(pdev);
From: Nishka Dasgupta nishkadg.linux@gmail.com
[ Upstream commit 9e38e690ace3e7a22a81fc02652fc101efb340cf ]
Each iteration of for_each_child_of_node() executes of_node_put() on the previous node, but in some return paths in the middle of the loop of_node_put() is missing thus causing a reference leak.
Hence stash these mid-loop return values in a variable 'err' and add a new label err_node_put which executes of_node_put() on the previous node and returns 'err' on failure.
Change mid-loop return statements to point to jump to this label to fix the reference leak.
Issue found with Coccinelle.
Signed-off-by: Nishka Dasgupta nishkadg.linux@gmail.com [lorenzo.pieralisi@arm.com: rewrote commit log] Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/pci-tegra.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c index 9a917b2456f6c..673a1725ef382 100644 --- a/drivers/pci/controller/pci-tegra.c +++ b/drivers/pci/controller/pci-tegra.c @@ -2237,14 +2237,15 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie) err = of_pci_get_devfn(port); if (err < 0) { dev_err(dev, "failed to parse address: %d\n", err); - return err; + goto err_node_put; }
index = PCI_SLOT(err);
if (index < 1 || index > soc->num_ports) { dev_err(dev, "invalid port number: %d\n", index); - return -EINVAL; + err = -EINVAL; + goto err_node_put; }
index--; @@ -2253,12 +2254,13 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie) if (err < 0) { dev_err(dev, "failed to parse # of lanes: %d\n", err); - return err; + goto err_node_put; }
if (value > 16) { dev_err(dev, "invalid # of lanes: %u\n", value); - return -EINVAL; + err = -EINVAL; + goto err_node_put; }
lanes |= value << (index << 3); @@ -2272,13 +2274,15 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie) lane += value;
rp = devm_kzalloc(dev, sizeof(*rp), GFP_KERNEL); - if (!rp) - return -ENOMEM; + if (!rp) { + err = -ENOMEM; + goto err_node_put; + }
err = of_address_to_resource(port, 0, &rp->regs); if (err < 0) { dev_err(dev, "failed to parse address: %d\n", err); - return err; + goto err_node_put; }
INIT_LIST_HEAD(&rp->list); @@ -2330,6 +2334,10 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie) return err;
return 0; + +err_node_put: + of_node_put(port); + return err; }
/*
From: Jason Gerecke killertofu@gmail.com
[ Upstream commit 073b50bccbbf99a3b79a1913604c656d0e1a56c9 ]
Addresses a few issues that were noticed when compiling with non-default warnings enabled. The trimmed-down warnings in the order they are fixed below are:
* declaration of 'size' shadows a parameter
* '%s' directive output may be truncated writing up to 5 bytes into a region of size between 1 and 64
* pointer targets in initialization of 'char *' from 'unsigned char *' differ in signedness
* left shift of negative value
Signed-off-by: Jason Gerecke jason.gerecke@wacom.com Reviewed-by: Aaron Armstrong Skomra aaron.skomra@wacom.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/wacom_sys.c | 7 ++++--- drivers/hid/wacom_wac.c | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 53bddb50aebaf..602219a8710d0 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -88,7 +88,7 @@ static void wacom_wac_queue_flush(struct hid_device *hdev, }
static int wacom_wac_pen_serial_enforce(struct hid_device *hdev, - struct hid_report *report, u8 *raw_data, int size) + struct hid_report *report, u8 *raw_data, int report_size) { struct wacom *wacom = hid_get_drvdata(hdev); struct wacom_wac *wacom_wac = &wacom->wacom_wac; @@ -149,7 +149,8 @@ static int wacom_wac_pen_serial_enforce(struct hid_device *hdev, if (flush) wacom_wac_queue_flush(hdev, &wacom_wac->pen_fifo); else if (insert) - wacom_wac_queue_insert(hdev, &wacom_wac->pen_fifo, raw_data, size); + wacom_wac_queue_insert(hdev, &wacom_wac->pen_fifo, + raw_data, report_size);
return insert && !flush; } @@ -2176,7 +2177,7 @@ static void wacom_update_name(struct wacom *wacom, const char *suffix) { struct wacom_wac *wacom_wac = &wacom->wacom_wac; struct wacom_features *features = &wacom_wac->features; - char name[WACOM_NAME_MAX]; + char name[WACOM_NAME_MAX - 20]; /* Leave some room for suffixes */
/* Generic devices name unspecified */ if ((features->type == HID_GENERIC) && !strcmp("Wacom HID", features->name)) { diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 1713235d28cb0..2b46403973755 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -251,7 +251,7 @@ static int wacom_dtu_irq(struct wacom_wac *wacom)
static int wacom_dtus_irq(struct wacom_wac *wacom) { - char *data = wacom->data; + unsigned char *data = wacom->data; struct input_dev *input = wacom->pen_input; unsigned short prox, pressure = 0;
@@ -572,7 +572,7 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) strip2 = ((data[3] & 0x1f) << 8) | data[4]; }
- prox = (buttons & ~(~0 << nbuttons)) | (keys & ~(~0 << nkeys)) | + prox = (buttons & ~(~0U << nbuttons)) | (keys & ~(~0U << nkeys)) | (ring1 & 0x80) | (ring2 & 0x80) | strip1 | strip2;
wacom_report_numbered_buttons(input, nbuttons, buttons);
From: Matti Vaittinen matti.vaittinen@fi.rohmeurope.com
[ Upstream commit 41a8e19f47dfe9154c56b35842700ad38a7c33e0 ]
With CONFIG_BD70528_WATCHDOG=m, a built-in rtc driver cannot call into the low-level functions that are part of the watchdog module:
drivers/rtc/rtc-bd70528.o: In function `bd70528_set_time': rtc-bd70528.c:(.text+0x22c): undefined reference to `bd70528_wdt_lock' rtc-bd70528.c:(.text+0x2a8): undefined reference to `bd70528_wdt_unlock' drivers/rtc/rtc-bd70528.o: In function `bd70528_set_rtc_based_timers': rtc-bd70528.c:(.text+0x50c): undefined reference to `bd70528_wdt_set'
Add a Kconfig dependency which forces RTC to be a module if watchdog is a module. If watchdog is not compiled at all the stub functions for watchdog control are used. compiling the RTC without watchdog is fine.
Fixes: 32a4a4ebf768 ("rtc: bd70528: Initial support for ROHM bd70528 RTC") Suggested-by: Arnd Bergmann arnd@arndb.de Reported-by: kbuild test robot lkp@intel.com Signed-off-by: Matti Vaittinen matti.vaittinen@fi.rohmeurope.com Link: https://lore.kernel.org/r/84462e01e43d39024948a3bdd24087ff87dc2255.156559138... Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/rtc/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index e72f65b61176d..add43c3374895 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -500,6 +500,7 @@ config RTC_DRV_M41T80_WDT watchdog timer in the ST M41T60 and M41T80 RTC chips series. config RTC_DRV_BD70528 tristate "ROHM BD70528 PMIC RTC" + depends on MFD_ROHM_BD70528 && (BD70528_WATCHDOG || !BD70528_WATCHDOG) help If you say Y here you will get support for the RTC on ROHM BD70528 Power Management IC.
From: Peter Zijlstra peterz@infradead.org
[ Upstream commit 1c6c1ca318585f1096d4d04bc722297c85e9fb8a ]
The comment describing the loongson_llsc_mb() reorder case doesn't make any sense what so ever. Instruction re-ordering is not an SMP artifact, but rather a CPU local phenomenon. Clarify the comment by explaining that these issue cause a coherence fail.
For the branch speculation case; if futex_atomic_cmpxchg_inatomic() needs one at the bne branch target, then surely the normal __cmpxch_asm() implementation does too. We cannot rely on the barriers from cmpxchg() because cmpxchg_local() is implemented with the same macro, and branch prediction and speculation are, too, CPU local.
Fixes: e02e07e3127d ("MIPS: Loongson: Introduce and use loongson_llsc_mb()") Cc: Huacai Chen chenhc@lemote.com Cc: Huang Pei huangpei@loongson.cn Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Signed-off-by: Paul Burton paul.burton@mips.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/include/asm/atomic.h | 5 +++-- arch/mips/include/asm/barrier.h | 32 ++++++++++++++++++-------------- arch/mips/include/asm/bitops.h | 5 +++++ arch/mips/include/asm/cmpxchg.h | 5 +++++ arch/mips/kernel/syscall.c | 1 + 5 files changed, 32 insertions(+), 16 deletions(-)
diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h index 9a82dd11c0e9e..190f1b6151221 100644 --- a/arch/mips/include/asm/atomic.h +++ b/arch/mips/include/asm/atomic.h @@ -193,6 +193,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) if (kernel_uses_llsc) { int temp;
+ loongson_llsc_mb(); __asm__ __volatile__( " .set push \n" " .set "MIPS_ISA_LEVEL" \n" @@ -200,12 +201,12 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) " .set pop \n" " subu %0, %1, %3 \n" " move %1, %0 \n" - " bltz %0, 1f \n" + " bltz %0, 2f \n" " .set push \n" " .set "MIPS_ISA_LEVEL" \n" " sc %1, %2 \n" "\t" __scbeqz " %1, 1b \n" - "1: \n" + "2: \n" " .set pop \n" : "=&r" (result), "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter) diff --git a/arch/mips/include/asm/barrier.h b/arch/mips/include/asm/barrier.h index b865e317a14f7..f9a6da96aae12 100644 --- a/arch/mips/include/asm/barrier.h +++ b/arch/mips/include/asm/barrier.h @@ -238,36 +238,40 @@
/* * Some Loongson 3 CPUs have a bug wherein execution of a memory access (load, - * store or pref) in between an ll & sc can cause the sc instruction to + * store or prefetch) in between an LL & SC can cause the SC instruction to * erroneously succeed, breaking atomicity. Whilst it's unusual to write code * containing such sequences, this bug bites harder than we might otherwise * expect due to reordering & speculation: * - * 1) A memory access appearing prior to the ll in program order may actually - * be executed after the ll - this is the reordering case. + * 1) A memory access appearing prior to the LL in program order may actually + * be executed after the LL - this is the reordering case. * - * In order to avoid this we need to place a memory barrier (ie. a sync - * instruction) prior to every ll instruction, in between it & any earlier - * memory access instructions. Many of these cases are already covered by - * smp_mb__before_llsc() but for the remaining cases, typically ones in - * which multiple CPUs may operate on a memory location but ordering is not - * usually guaranteed, we use loongson_llsc_mb() below. + * In order to avoid this we need to place a memory barrier (ie. a SYNC + * instruction) prior to every LL instruction, in between it and any earlier + * memory access instructions. * * This reordering case is fixed by 3A R2 CPUs, ie. 3A2000 models and later. * - * 2) If a conditional branch exists between an ll & sc with a target outside - * of the ll-sc loop, for example an exit upon value mismatch in cmpxchg() + * 2) If a conditional branch exists between an LL & SC with a target outside + * of the LL-SC loop, for example an exit upon value mismatch in cmpxchg() * or similar, then misprediction of the branch may allow speculative - * execution of memory accesses from outside of the ll-sc loop. + * execution of memory accesses from outside of the LL-SC loop. * - * In order to avoid this we need a memory barrier (ie. a sync instruction) + * In order to avoid this we need a memory barrier (ie. a SYNC instruction) * at each affected branch target, for which we also use loongson_llsc_mb() * defined below. * * This case affects all current Loongson 3 CPUs. + * + * The above described cases cause an error in the cache coherence protocol; + * such that the Invalidate of a competing LL-SC goes 'missing' and SC + * erroneously observes its core still has Exclusive state and lets the SC + * proceed. + * + * Therefore the error only occurs on SMP systems. */ #ifdef CONFIG_CPU_LOONGSON3_WORKAROUNDS /* Loongson-3's LLSC workaround */ -#define loongson_llsc_mb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory") +#define loongson_llsc_mb() __asm__ __volatile__("sync" : : :"memory") #else #define loongson_llsc_mb() do { } while (0) #endif diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h index 9a466dde9b96a..7bd35e5e2a9e4 100644 --- a/arch/mips/include/asm/bitops.h +++ b/arch/mips/include/asm/bitops.h @@ -249,6 +249,7 @@ static inline int test_and_set_bit(unsigned long nr, unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp;
+ loongson_llsc_mb(); do { __asm__ __volatile__( " .set push \n" @@ -305,6 +306,7 @@ static inline int test_and_set_bit_lock(unsigned long nr, unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp;
+ loongson_llsc_mb(); do { __asm__ __volatile__( " .set push \n" @@ -364,6 +366,7 @@ static inline int test_and_clear_bit(unsigned long nr, unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp;
+ loongson_llsc_mb(); do { __asm__ __volatile__( " " __LL "%0, %1 # test_and_clear_bit \n" @@ -379,6 +382,7 @@ static inline int test_and_clear_bit(unsigned long nr, unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp;
+ loongson_llsc_mb(); do { __asm__ __volatile__( " .set push \n" @@ -438,6 +442,7 @@ static inline int test_and_change_bit(unsigned long nr, unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp;
+ loongson_llsc_mb(); do { __asm__ __volatile__( " .set push \n" diff --git a/arch/mips/include/asm/cmpxchg.h b/arch/mips/include/asm/cmpxchg.h index f345a873742d9..f5994a332673b 100644 --- a/arch/mips/include/asm/cmpxchg.h +++ b/arch/mips/include/asm/cmpxchg.h @@ -46,6 +46,7 @@ extern unsigned long __xchg_called_with_bad_pointer(void) __typeof(*(m)) __ret; \ \ if (kernel_uses_llsc) { \ + loongson_llsc_mb(); \ __asm__ __volatile__( \ " .set push \n" \ " .set noat \n" \ @@ -117,6 +118,7 @@ static inline unsigned long __xchg(volatile void *ptr, unsigned long x, __typeof(*(m)) __ret; \ \ if (kernel_uses_llsc) { \ + loongson_llsc_mb(); \ __asm__ __volatile__( \ " .set push \n" \ " .set noat \n" \ @@ -134,6 +136,7 @@ static inline unsigned long __xchg(volatile void *ptr, unsigned long x, : "=&r" (__ret), "=" GCC_OFF_SMALL_ASM() (*m) \ : GCC_OFF_SMALL_ASM() (*m), "Jr" (old), "Jr" (new) \ : "memory"); \ + loongson_llsc_mb(); \ } else { \ unsigned long __flags; \ \ @@ -229,6 +232,7 @@ static inline unsigned long __cmpxchg64(volatile void *ptr, */ local_irq_save(flags);
+ loongson_llsc_mb(); asm volatile( " .set push \n" " .set " MIPS_ISA_ARCH_LEVEL " \n" @@ -274,6 +278,7 @@ static inline unsigned long __cmpxchg64(volatile void *ptr, "r" (old), "r" (new) : "memory"); + loongson_llsc_mb();
local_irq_restore(flags); return ret; diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index b6dc78ad5d8c0..b0e25e913bdb9 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -132,6 +132,7 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new) [efault] "i" (-EFAULT) : "memory"); } else if (cpu_has_llsc) { + loongson_llsc_mb(); __asm__ __volatile__ ( " .set push \n" " .set "MIPS_ISA_ARCH_LEVEL" \n"
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit f58ba5e3f6863ea4486952698898848a6db726c2 ]
Fix build errors when building almost-allmodconfig but with SYSFS not set (not enabled). Fixes these build errors:
ERROR: "pci_destroy_slot" [drivers/pci/controller/pci-hyperv.ko] undefined! ERROR: "pci_create_slot" [drivers/pci/controller/pci-hyperv.ko] undefined!
drivers/pci/slot.o is only built when SYSFS is enabled, so pci-hyperv.o has an implicit dependency on SYSFS. Make that explicit.
Also, depending on X86 && X86_64 is not needed, so just change that to depend on X86_64.
Fixes: a15f2c08c708 ("PCI: hv: support reporting serial number as slot information") Signed-off-by: Randy Dunlap rdunlap@infradead.org Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: Haiyang Zhang haiyangz@microsoft.com Cc: Matthew Wilcox willy@infradead.org Cc: Jake Oshins jakeo@microsoft.com Cc: "K. Y. Srinivasan" kys@microsoft.com Cc: Haiyang Zhang haiyangz@microsoft.com Cc: Stephen Hemminger sthemmin@microsoft.com Cc: Stephen Hemminger stephen@networkplumber.org Cc: Sasha Levin sashal@kernel.org Cc: Bjorn Helgaas bhelgaas@google.com Cc: linux-pci@vger.kernel.org Cc: linux-hyperv@vger.kernel.org Cc: Dexuan Cui decui@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 2ab92409210af..297bf928d6522 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -181,7 +181,7 @@ config PCI_LABEL
config PCI_HYPERV tristate "Hyper-V PCI Frontend" - depends on X86 && HYPERV && PCI_MSI && PCI_MSI_IRQ_DOMAIN && X86_64 + depends on X86_64 && HYPERV && PCI_MSI && PCI_MSI_IRQ_DOMAIN && SYSFS help The PCI device frontend driver allows the kernel to import arbitrary PCI devices from a PCI backend to support PCI driver domains.
From: Xiaowei Bao xiaowei.bao@nxp.com
[ Upstream commit fd5d16531a39322c3d7433d9f8a36203c9aaeddc ]
The layerscape PCIe controller have 4 BARs.
BAR0 and BAR1 are 32bit, BAR2 and BAR4 are 64bit and that's a fixed hardware configuration.
Set the bar_fixed_64bit variable accordingly.
Signed-off-by: Xiaowei Bao xiaowei.bao@nxp.com [lorenzo.pieralisi@arm.com: commit log] Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Acked-by: Kishon Vijay Abraham I kishon@ti.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/dwc/pci-layerscape-ep.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c index be61d96cc95ed..ca9aa4501e7e9 100644 --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c @@ -44,6 +44,7 @@ static const struct pci_epc_features ls_pcie_epc_features = { .linkup_notifier = false, .msi_capable = true, .msix_capable = false, + .bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4), };
static const struct pci_epc_features*
From: Miroslav Benes mbenes@suse.cz
[ Upstream commit 4ff96fb52c6964ad42e0a878be8f86a2e8052ddd ]
klp_module_coming() is called for every module appearing in the system. It sets obj->mod to a patched module for klp_object obj. Unfortunately it leaves it set even if an error happens later in the function and the patched module is not allowed to be loaded.
klp_is_object_loaded() uses obj->mod variable and could currently give a wrong return value. The bug is probably harmless as of now.
Signed-off-by: Miroslav Benes mbenes@suse.cz Reviewed-by: Petr Mladek pmladek@suse.com Acked-by: Josh Poimboeuf jpoimboe@redhat.com Signed-off-by: Petr Mladek pmladek@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/livepatch/core.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index c4ce08f43bd63..ab4a4606d19b7 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -1175,6 +1175,7 @@ int klp_module_coming(struct module *mod) pr_warn("patch '%s' failed for module '%s', refusing to load module '%s'\n", patch->mod->name, obj->mod->name, obj->mod->name); mod->klp_alive = false; + obj->mod = NULL; klp_cleanup_module_patches_limited(mod, patch); mutex_unlock(&klp_mutex);
From: Peter Zijlstra peterz@infradead.org
[ Upstream commit 42344113ba7a1ed7b5654cd5270af0d5698d8521 ]
Recent probing at the Linux Kernel Memory Model uncovered a 'surprise'. Strongly ordered architectures where the atomic RmW primitive implies full memory ordering and smp_mb__{before,after}_atomic() are a simple barrier() (such as MIPS without WEAK_REORDERING_BEYOND_LLSC) fail for:
*x = 1; atomic_inc(u); smp_mb__after_atomic(); r0 = *y;
Because, while the atomic_inc() implies memory order, it (surprisingly) does not provide a compiler barrier. This then allows the compiler to re-order like so:
atomic_inc(u); *x = 1; smp_mb__after_atomic(); r0 = *y;
Which the CPU is then allowed to re-order (under TSO rules) like:
atomic_inc(u); r0 = *y; *x = 1;
And this very much was not intended. Therefore strengthen the atomic RmW ops to include a compiler barrier.
Reported-by: Andrea Parri andrea.parri@amarulasolutions.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Signed-off-by: Paul Burton paul.burton@mips.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/include/asm/atomic.h | 14 +++++------ arch/mips/include/asm/barrier.h | 12 ++++++++-- arch/mips/include/asm/bitops.h | 42 ++++++++++++++++++++------------- arch/mips/include/asm/cmpxchg.h | 6 ++--- 4 files changed, 45 insertions(+), 29 deletions(-)
diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h index 190f1b6151221..bb8658cc7f126 100644 --- a/arch/mips/include/asm/atomic.h +++ b/arch/mips/include/asm/atomic.h @@ -68,7 +68,7 @@ static __inline__ void atomic_##op(int i, atomic_t * v) \ "\t" __scbeqz " %0, 1b \n" \ " .set pop \n" \ : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter) \ - : "Ir" (i)); \ + : "Ir" (i) : __LLSC_CLOBBER); \ } else { \ unsigned long flags; \ \ @@ -98,7 +98,7 @@ static __inline__ int atomic_##op##_return_relaxed(int i, atomic_t * v) \ " .set pop \n" \ : "=&r" (result), "=&r" (temp), \ "+" GCC_OFF_SMALL_ASM() (v->counter) \ - : "Ir" (i)); \ + : "Ir" (i) : __LLSC_CLOBBER); \ } else { \ unsigned long flags; \ \ @@ -132,7 +132,7 @@ static __inline__ int atomic_fetch_##op##_relaxed(int i, atomic_t * v) \ " move %0, %1 \n" \ : "=&r" (result), "=&r" (temp), \ "+" GCC_OFF_SMALL_ASM() (v->counter) \ - : "Ir" (i)); \ + : "Ir" (i) : __LLSC_CLOBBER); \ } else { \ unsigned long flags; \ \ @@ -210,7 +210,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) " .set pop \n" : "=&r" (result), "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter) - : "Ir" (i)); + : "Ir" (i) : __LLSC_CLOBBER); } else { unsigned long flags;
@@ -270,7 +270,7 @@ static __inline__ void atomic64_##op(s64 i, atomic64_t * v) \ "\t" __scbeqz " %0, 1b \n" \ " .set pop \n" \ : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter) \ - : "Ir" (i)); \ + : "Ir" (i) : __LLSC_CLOBBER); \ } else { \ unsigned long flags; \ \ @@ -300,7 +300,7 @@ static __inline__ s64 atomic64_##op##_return_relaxed(s64 i, atomic64_t * v) \ " .set pop \n" \ : "=&r" (result), "=&r" (temp), \ "+" GCC_OFF_SMALL_ASM() (v->counter) \ - : "Ir" (i)); \ + : "Ir" (i) : __LLSC_CLOBBER); \ } else { \ unsigned long flags; \ \ @@ -334,7 +334,7 @@ static __inline__ s64 atomic64_fetch_##op##_relaxed(s64 i, atomic64_t * v) \ " .set pop \n" \ : "=&r" (result), "=&r" (temp), \ "+" GCC_OFF_SMALL_ASM() (v->counter) \ - : "Ir" (i)); \ + : "Ir" (i) : __LLSC_CLOBBER); \ } else { \ unsigned long flags; \ \ diff --git a/arch/mips/include/asm/barrier.h b/arch/mips/include/asm/barrier.h index f9a6da96aae12..9228f73862205 100644 --- a/arch/mips/include/asm/barrier.h +++ b/arch/mips/include/asm/barrier.h @@ -211,14 +211,22 @@ #define __smp_wmb() barrier() #endif
+/* + * When LL/SC does imply order, it must also be a compiler barrier to avoid the + * compiler from reordering where the CPU will not. When it does not imply + * order, the compiler is also free to reorder across the LL/SC loop and + * ordering will be done by smp_llsc_mb() and friends. + */ #if defined(CONFIG_WEAK_REORDERING_BEYOND_LLSC) && defined(CONFIG_SMP) #define __WEAK_LLSC_MB " sync \n" +#define smp_llsc_mb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory") +#define __LLSC_CLOBBER #else #define __WEAK_LLSC_MB " \n" +#define smp_llsc_mb() do { } while (0) +#define __LLSC_CLOBBER "memory" #endif
-#define smp_llsc_mb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory") - #ifdef CONFIG_CPU_CAVIUM_OCTEON #define smp_mb__before_llsc() smp_wmb() #define __smp_mb__before_llsc() __smp_wmb() diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h index 7bd35e5e2a9e4..985d6a02f9ea1 100644 --- a/arch/mips/include/asm/bitops.h +++ b/arch/mips/include/asm/bitops.h @@ -66,7 +66,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) " beqzl %0, 1b \n" " .set pop \n" : "=&r" (temp), "=" GCC_OFF_SMALL_ASM() (*m) - : "ir" (1UL << bit), GCC_OFF_SMALL_ASM() (*m)); + : "ir" (1UL << bit), GCC_OFF_SMALL_ASM() (*m) + : __LLSC_CLOBBER); #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { loongson_llsc_mb(); @@ -76,7 +77,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) " " __INS "%0, %3, %2, 1 \n" " " __SC "%0, %1 \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m) - : "ir" (bit), "r" (~0)); + : "ir" (bit), "r" (~0) + : __LLSC_CLOBBER); } while (unlikely(!temp)); #endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */ } else if (kernel_uses_llsc) { @@ -90,7 +92,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) " " __SC "%0, %1 \n" " .set pop \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m) - : "ir" (1UL << bit)); + : "ir" (1UL << bit) + : __LLSC_CLOBBER); } while (unlikely(!temp)); } else __mips_set_bit(nr, addr); @@ -122,7 +125,8 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) " beqzl %0, 1b \n" " .set pop \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m) - : "ir" (~(1UL << bit))); + : "ir" (~(1UL << bit)) + : __LLSC_CLOBBER); #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { loongson_llsc_mb(); @@ -132,7 +136,8 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) " " __INS "%0, $0, %2, 1 \n" " " __SC "%0, %1 \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m) - : "ir" (bit)); + : "ir" (bit) + : __LLSC_CLOBBER); } while (unlikely(!temp)); #endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */ } else if (kernel_uses_llsc) { @@ -146,7 +151,8 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) " " __SC "%0, %1 \n" " .set pop \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m) - : "ir" (~(1UL << bit))); + : "ir" (~(1UL << bit)) + : __LLSC_CLOBBER); } while (unlikely(!temp)); } else __mips_clear_bit(nr, addr); @@ -192,7 +198,8 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) " beqzl %0, 1b \n" " .set pop \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m) - : "ir" (1UL << bit)); + : "ir" (1UL << bit) + : __LLSC_CLOBBER); } else if (kernel_uses_llsc) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; @@ -207,7 +214,8 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) " " __SC "%0, %1 \n" " .set pop \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m) - : "ir" (1UL << bit)); + : "ir" (1UL << bit) + : __LLSC_CLOBBER); } while (unlikely(!temp)); } else __mips_change_bit(nr, addr); @@ -244,7 +252,7 @@ static inline int test_and_set_bit(unsigned long nr, " .set pop \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res) : "r" (1UL << bit) - : "memory"); + : __LLSC_CLOBBER); } else if (kernel_uses_llsc) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; @@ -260,7 +268,7 @@ static inline int test_and_set_bit(unsigned long nr, " .set pop \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res) : "r" (1UL << bit) - : "memory"); + : __LLSC_CLOBBER); } while (unlikely(!res));
res = temp & (1UL << bit); @@ -301,7 +309,7 @@ static inline int test_and_set_bit_lock(unsigned long nr, " .set pop \n" : "=&r" (temp), "+m" (*m), "=&r" (res) : "r" (1UL << bit) - : "memory"); + : __LLSC_CLOBBER); } else if (kernel_uses_llsc) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; @@ -317,7 +325,7 @@ static inline int test_and_set_bit_lock(unsigned long nr, " .set pop \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res) : "r" (1UL << bit) - : "memory"); + : __LLSC_CLOBBER); } while (unlikely(!res));
res = temp & (1UL << bit); @@ -360,7 +368,7 @@ static inline int test_and_clear_bit(unsigned long nr, " .set pop \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res) : "r" (1UL << bit) - : "memory"); + : __LLSC_CLOBBER); #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) } else if (kernel_uses_llsc && __builtin_constant_p(nr)) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); @@ -375,7 +383,7 @@ static inline int test_and_clear_bit(unsigned long nr, " " __SC "%0, %1 \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res) : "ir" (bit) - : "memory"); + : __LLSC_CLOBBER); } while (unlikely(!temp)); #endif } else if (kernel_uses_llsc) { @@ -394,7 +402,7 @@ static inline int test_and_clear_bit(unsigned long nr, " .set pop \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res) : "r" (1UL << bit) - : "memory"); + : __LLSC_CLOBBER); } while (unlikely(!res));
res = temp & (1UL << bit); @@ -437,7 +445,7 @@ static inline int test_and_change_bit(unsigned long nr, " .set pop \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res) : "r" (1UL << bit) - : "memory"); + : __LLSC_CLOBBER); } else if (kernel_uses_llsc) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; @@ -453,7 +461,7 @@ static inline int test_and_change_bit(unsigned long nr, " .set pop \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res) : "r" (1UL << bit) - : "memory"); + : __LLSC_CLOBBER); } while (unlikely(!res));
res = temp & (1UL << bit); diff --git a/arch/mips/include/asm/cmpxchg.h b/arch/mips/include/asm/cmpxchg.h index f5994a332673b..c8a47d18f6288 100644 --- a/arch/mips/include/asm/cmpxchg.h +++ b/arch/mips/include/asm/cmpxchg.h @@ -61,7 +61,7 @@ extern unsigned long __xchg_called_with_bad_pointer(void) " .set pop \n" \ : "=&r" (__ret), "=" GCC_OFF_SMALL_ASM() (*m) \ : GCC_OFF_SMALL_ASM() (*m), "Jr" (val) \ - : "memory"); \ + : __LLSC_CLOBBER); \ } else { \ unsigned long __flags; \ \ @@ -134,8 +134,8 @@ static inline unsigned long __xchg(volatile void *ptr, unsigned long x, " .set pop \n" \ "2: \n" \ : "=&r" (__ret), "=" GCC_OFF_SMALL_ASM() (*m) \ - : GCC_OFF_SMALL_ASM() (*m), "Jr" (old), "Jr" (new) \ - : "memory"); \ + : GCC_OFF_SMALL_ASM() (*m), "Jr" (old), "Jr" (new) \ + : __LLSC_CLOBBER); \ loongson_llsc_mb(); \ } else { \ unsigned long __flags; \
From: Will Deacon will@kernel.org
[ Upstream commit 834020366da9ab3fb87d1eb9a3160eb22dbed63a ]
Translation faults arising from cache maintenance instructions are rather unhelpfully reported with an FSR value where the WnR field is set to 1, indicating that the faulting access was a write. Since cache maintenance instructions on 32-bit ARM do not require any particular permissions, this can cause our private 'cacheflush' system call to fail spuriously if a translation fault is generated due to page aging when targetting a read-only VMA.
In this situation, we will return -EFAULT to userspace, although this is unfortunately suppressed by the popular '__builtin___clear_cache()' intrinsic provided by GCC, which returns void.
Although it's tempting to write this off as a userspace issue, we can actually do a little bit better on CPUs that support LPAE, even if the short-descriptor format is in use. On these CPUs, cache maintenance faults additionally set the CM field in the FSR, which we can use to suppress the write permission checks in the page fault handler and succeed in performing cache maintenance to read-only areas even in the presence of a translation fault.
Reported-by: Orion Hodson oth@google.com Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Russell King rmk+kernel@armlinux.org.uk Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mm/fault.c | 4 ++-- arch/arm/mm/fault.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 890eeaac3cbba..bd0f4821f7e11 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -191,7 +191,7 @@ static inline bool access_error(unsigned int fsr, struct vm_area_struct *vma) { unsigned int mask = VM_READ | VM_WRITE | VM_EXEC;
- if (fsr & FSR_WRITE) + if ((fsr & FSR_WRITE) && !(fsr & FSR_CM)) mask = VM_WRITE; if (fsr & FSR_LNX_PF) mask = VM_EXEC; @@ -262,7 +262,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
if (user_mode(regs)) flags |= FAULT_FLAG_USER; - if (fsr & FSR_WRITE) + if ((fsr & FSR_WRITE) && !(fsr & FSR_CM)) flags |= FAULT_FLAG_WRITE;
/* diff --git a/arch/arm/mm/fault.h b/arch/arm/mm/fault.h index c063708fa5032..9ecc2097a87a0 100644 --- a/arch/arm/mm/fault.h +++ b/arch/arm/mm/fault.h @@ -6,6 +6,7 @@ * Fault status register encodings. We steal bit 31 for our own purposes. */ #define FSR_LNX_PF (1 << 31) +#define FSR_CM (1 << 13) #define FSR_WRITE (1 << 11) #define FSR_FS4 (1 << 10) #define FSR_FS3_0 (15)
From: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com
[ Upstream commit 18046335643de6d21327f5ae034c8fb8463f6715 ]
On all released Intel controllers (CNL/CML/ICL), PDI2 reports an invalid count, force the correct hardware-supported value
This may have to be revisited with platform-specific values if the hardware changes, but for now this is good enough.
Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Link: https://lore.kernel.org/r/20190806005522.22642-3-pierre-louis.bossart@linux.... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soundwire/intel.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c index 317873bc0555d..ec25a71d08873 100644 --- a/drivers/soundwire/intel.c +++ b/drivers/soundwire/intel.c @@ -289,6 +289,16 @@ intel_pdi_get_ch_cap(struct sdw_intel *sdw, unsigned int pdi_num, bool pcm)
if (pcm) { count = intel_readw(shim, SDW_SHIM_PCMSYCHC(link_id, pdi_num)); + + /* + * WORKAROUND: on all existing Intel controllers, pdi + * number 2 reports channel count as 1 even though it + * supports 8 channels. Performing hardcoding for pdi + * number 2. + */ + if (pdi_num == 2) + count = 7; + } else { count = intel_readw(shim, SDW_SHIM_PDMSCAP(link_id)); count = ((count & SDW_SHIM_PDMSCAP_CPSS) >>
From: Hou Zhiqiang Zhiqiang.Hou@nxp.com
[ Upstream commit df901c85cc28b538c62f6bc20b16a8bd05fcb756 ]
Current code erroneously sets-up the CPU base address through the parameter 'pci_addr', which is passed to initialize the CPU (AXI) base address of the inbound window where the controller maps the PCI address space into CPU physical address space; furthermore, it also truncates it by programming only the lower 32-bit value into the inbound CPU address register.
Fix both issues by introducing a new parameter 'u64 cpu_addr' to initialize both lower 32-bit and upper 32-bit of the CPU physical base address mapping PCI inbound transactions into CPU (AXI) ones.
Fixes: 9af6bcb11e12 ("PCI: mobiveil: Add Mobiveil PCIe Host Bridge IP driver") Signed-off-by: Hou Zhiqiang Zhiqiang.Hou@nxp.com Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: Minghuan Lian Minghuan.Lian@nxp.com Reviewed-by: Subrahmanya Lingappa l.subrahmanya@mobiveil.co.in Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/pcie-mobiveil.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c index 672e633601c78..a45a6447b01d9 100644 --- a/drivers/pci/controller/pcie-mobiveil.c +++ b/drivers/pci/controller/pcie-mobiveil.c @@ -88,6 +88,7 @@ #define AMAP_CTRL_TYPE_MASK 3
#define PAB_EXT_PEX_AMAP_SIZEN(win) PAB_EXT_REG_ADDR(0xbef0, win) +#define PAB_EXT_PEX_AMAP_AXI_WIN(win) PAB_EXT_REG_ADDR(0xb4a0, win) #define PAB_PEX_AMAP_AXI_WIN(win) PAB_REG_ADDR(0x4ba4, win) #define PAB_PEX_AMAP_PEX_WIN_L(win) PAB_REG_ADDR(0x4ba8, win) #define PAB_PEX_AMAP_PEX_WIN_H(win) PAB_REG_ADDR(0x4bac, win) @@ -462,7 +463,7 @@ static int mobiveil_pcie_parse_dt(struct mobiveil_pcie *pcie) }
static void program_ib_windows(struct mobiveil_pcie *pcie, int win_num, - u64 pci_addr, u32 type, u64 size) + u64 cpu_addr, u64 pci_addr, u32 type, u64 size) { u32 value; u64 size64 = ~(size - 1); @@ -482,7 +483,10 @@ static void program_ib_windows(struct mobiveil_pcie *pcie, int win_num, csr_writel(pcie, upper_32_bits(size64), PAB_EXT_PEX_AMAP_SIZEN(win_num));
- csr_writel(pcie, pci_addr, PAB_PEX_AMAP_AXI_WIN(win_num)); + csr_writel(pcie, lower_32_bits(cpu_addr), + PAB_PEX_AMAP_AXI_WIN(win_num)); + csr_writel(pcie, upper_32_bits(cpu_addr), + PAB_EXT_PEX_AMAP_AXI_WIN(win_num));
csr_writel(pcie, lower_32_bits(pci_addr), PAB_PEX_AMAP_PEX_WIN_L(win_num)); @@ -624,7 +628,7 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie) CFG_WINDOW_TYPE, resource_size(pcie->ob_io_res));
/* memory inbound translation window */ - program_ib_windows(pcie, WIN_NUM_0, 0, MEM_WINDOW_TYPE, IB_WIN_SIZE); + program_ib_windows(pcie, WIN_NUM_0, 0, 0, MEM_WINDOW_TYPE, IB_WIN_SIZE);
/* Get the I/O and memory ranges from DT */ resource_list_for_each_entry(win, &pcie->resources) {
From: Nick Desaulniers ndesaulniers@google.com
[ Upstream commit a05b9608456e0d4464c6f7ca8572324ace57a3f4 ]
Clang produces references to __aeabi_uidivmod and __aeabi_idivmod for arm-linux-gnueabi and arm-linux-gnueabihf targets incorrectly when AEABI is not selected (such as when OABI_COMPAT is selected).
While this means that OABI userspaces wont be able to upgraded to kernels built with Clang, it means that boards that don't enable AEABI like s3c2410_defconfig will stop failing to link in KernelCI when built with Clang.
Link: https://github.com/ClangBuiltLinux/linux/issues/482 Link: https://groups.google.com/forum/#%21msg/clang-built-linux/yydsAAux5hk/GxjqJS...
Suggested-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Nick Desaulniers ndesaulniers@google.com Reviewed-by: Arnd Bergmann arnd@arndb.de Reviewed-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Russell King rmk+kernel@armlinux.org.uk Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/Kconfig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 24360211534ab..5e2c68e9dd6e2 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1572,8 +1572,9 @@ config ARM_PATCH_IDIV code to do integer division.
config AEABI - bool "Use the ARM EABI to compile the kernel" if !CPU_V7 && !CPU_V7M && !CPU_V6 && !CPU_V6K - default CPU_V7 || CPU_V7M || CPU_V6 || CPU_V6K + bool "Use the ARM EABI to compile the kernel" if !CPU_V7 && \ + !CPU_V7M && !CPU_V6 && !CPU_V6K && !CC_IS_CLANG + default CPU_V7 || CPU_V7M || CPU_V6 || CPU_V6K || CC_IS_CLANG help This option allows for the kernel to be compiled using the latest ARM ABI (aka EABI). This is only useful if you are using a user
From: Martin Blumenstingl martin.blumenstingl@googlemail.com
[ Upstream commit ed90302be64a53d9031c8ce05428c358b16a5d96 ]
The mainline PCIe PHY driver has it's own devicetree node. Update the clock alias so the mainline driver finds the clocks.
The first PCIe PHY is located at 0x1f106800 and exists on VRX200, ARX300 and GRX390. The second PCIe PHY is located at 0x1f700400 and exists on ARX300 and GRX390. The third PCIe PHY is located at 0x1f106a00 and exists onl on GRX390. Lantiq's board support package (called "UGW") names these registers "PDI".
Signed-off-by: Martin Blumenstingl martin.blumenstingl@googlemail.com Signed-off-by: Paul Burton paul.burton@mips.com Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Cc: john@phrozen.org Cc: kishon@ti.com Cc: ralf@linux-mips.org Cc: robh+dt@kernel.org Cc: linux-kernel@vger.kernel.org Cc: hauke@hauke-m.de Cc: mark.rutland@arm.com Cc: ms@dev.tdt.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/lantiq/xway/sysctrl.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c index b4323b2214e20..156a95ac5c725 100644 --- a/arch/mips/lantiq/xway/sysctrl.c +++ b/arch/mips/lantiq/xway/sysctrl.c @@ -468,14 +468,14 @@ void __init ltq_soc_init(void) clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 2, PMU_ANALOG_USB0_P); clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 2, PMU_ANALOG_USB1_P); /* rc 0 */ - clkdev_add_pmu("1d900000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE0_P); + clkdev_add_pmu("1f106800.phy", "phy", 1, 2, PMU_ANALOG_PCIE0_P); clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI); - clkdev_add_pmu("1d900000.pcie", "pdi", 1, 1, PMU1_PCIE_PDI); + clkdev_add_pmu("1f106800.phy", "pdi", 1, 1, PMU1_PCIE_PDI); clkdev_add_pmu("1d900000.pcie", "ctl", 1, 1, PMU1_PCIE_CTL); /* rc 1 */ - clkdev_add_pmu("19000000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE1_P); + clkdev_add_pmu("1f700400.phy", "phy", 1, 2, PMU_ANALOG_PCIE1_P); clkdev_add_pmu("19000000.pcie", "msi", 1, 1, PMU1_PCIE1_MSI); - clkdev_add_pmu("19000000.pcie", "pdi", 1, 1, PMU1_PCIE1_PDI); + clkdev_add_pmu("1f700400.phy", "pdi", 1, 1, PMU1_PCIE1_PDI); clkdev_add_pmu("19000000.pcie", "ctl", 1, 1, PMU1_PCIE1_CTL); }
@@ -499,9 +499,9 @@ void __init ltq_soc_init(void) clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0); clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1); /* rc 2 */ - clkdev_add_pmu("1a800000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE2_P); + clkdev_add_pmu("1f106a00.pcie", "phy", 1, 2, PMU_ANALOG_PCIE2_P); clkdev_add_pmu("1a800000.pcie", "msi", 1, 1, PMU1_PCIE2_MSI); - clkdev_add_pmu("1a800000.pcie", "pdi", 1, 1, PMU1_PCIE2_PDI); + clkdev_add_pmu("1f106a00.pcie", "pdi", 1, 1, PMU1_PCIE2_PDI); clkdev_add_pmu("1a800000.pcie", "ctl", 1, 1, PMU1_PCIE2_CTL); clkdev_add_pmu("1e10b308.eth", NULL, 0, 0, PMU_SWITCH | PMU_PPE_DP); clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF); @@ -526,10 +526,10 @@ void __init ltq_soc_init(void) clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0 | PMU_AHBM); clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 0, PMU_USB1_P); clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1 | PMU_AHBM); - clkdev_add_pmu("1d900000.pcie", "phy", 1, 1, PMU1_PCIE_PHY); + clkdev_add_pmu("1f106800.phy", "phy", 1, 1, PMU1_PCIE_PHY); clkdev_add_pmu("1d900000.pcie", "bus", 1, 0, PMU_PCIE_CLK); clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI); - clkdev_add_pmu("1d900000.pcie", "pdi", 1, 1, PMU1_PCIE_PDI); + clkdev_add_pmu("1f106800.phy", "pdi", 1, 1, PMU1_PCIE_PDI); clkdev_add_pmu("1d900000.pcie", "ctl", 1, 1, PMU1_PCIE_CTL); clkdev_add_pmu(NULL, "ahb", 1, 0, PMU_AHBM | PMU_AHBS);
From: Florian Fainelli f.fainelli@gmail.com
[ Upstream commit feb4eb060c3aecc3c5076bebe699cd09f1133c41 ]
When building on a 64-bit host, we will get warnings like those:
drivers/firmware/broadcom/bcm47xx_nvram.c:103:3: note: in expansion of macro 'pr_err' pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n", ^~~~~~ drivers/firmware/broadcom/bcm47xx_nvram.c:103:28: note: format string is defined here pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n", ~^ %li
Use %zu instead for that purpose.
Signed-off-by: Florian Fainelli f.fainelli@gmail.com Reviewed-by: Philippe Mathieu-Daudé f4bug@amsat.org Signed-off-by: Paul Burton paul.burton@mips.com Cc: linux-mips@linux-mips.org Cc: joe@perches.com Cc: Rafał Miłecki zajec5@gmail.com Cc: linux-mips@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/firmware/broadcom/bcm47xx_nvram.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/firmware/broadcom/bcm47xx_nvram.c b/drivers/firmware/broadcom/bcm47xx_nvram.c index 77eb74666ecbc..6d2820f6aca13 100644 --- a/drivers/firmware/broadcom/bcm47xx_nvram.c +++ b/drivers/firmware/broadcom/bcm47xx_nvram.c @@ -96,7 +96,7 @@ static int nvram_find_and_copy(void __iomem *iobase, u32 lim) nvram_len = size; } if (nvram_len >= NVRAM_SPACE) { - pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n", + pr_err("nvram on flash (%zu bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n", nvram_len, NVRAM_SPACE - 1); nvram_len = NVRAM_SPACE - 1; } @@ -148,7 +148,7 @@ static int nvram_init(void) header.len > sizeof(header)) { nvram_len = header.len; if (nvram_len >= NVRAM_SPACE) { - pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n", + pr_err("nvram on flash (%zu bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n", header.len, NVRAM_SPACE); nvram_len = NVRAM_SPACE - 1; }
On 9/29/2019 10:30 AM, Sasha Levin wrote:
From: Florian Fainelli f.fainelli@gmail.com
[ Upstream commit feb4eb060c3aecc3c5076bebe699cd09f1133c41 ]
When building on a 64-bit host, we will get warnings like those:
drivers/firmware/broadcom/bcm47xx_nvram.c:103:3: note: in expansion of macro 'pr_err' pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n", ^~~~~~ drivers/firmware/broadcom/bcm47xx_nvram.c:103:28: note: format string is defined here pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n", ~^ %li
Use %zu instead for that purpose.
This is not a fix that should be backported as it was done only to allow the driver to the made buildable with COMPILE_TEST. Please drop it from your auto-selection.
Signed-off-by: Florian Fainelli f.fainelli@gmail.com Reviewed-by: Philippe Mathieu-Daudé f4bug@amsat.org Signed-off-by: Paul Burton paul.burton@mips.com Cc: linux-mips@linux-mips.org Cc: joe@perches.com Cc: Rafał Miłecki zajec5@gmail.com Cc: linux-mips@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Sasha Levin sashal@kernel.org
drivers/firmware/broadcom/bcm47xx_nvram.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/firmware/broadcom/bcm47xx_nvram.c b/drivers/firmware/broadcom/bcm47xx_nvram.c index 77eb74666ecbc..6d2820f6aca13 100644 --- a/drivers/firmware/broadcom/bcm47xx_nvram.c +++ b/drivers/firmware/broadcom/bcm47xx_nvram.c @@ -96,7 +96,7 @@ static int nvram_find_and_copy(void __iomem *iobase, u32 lim) nvram_len = size; } if (nvram_len >= NVRAM_SPACE) {
pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n",
nvram_len = NVRAM_SPACE - 1; }pr_err("nvram on flash (%zu bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n", nvram_len, NVRAM_SPACE - 1);
@@ -148,7 +148,7 @@ static int nvram_init(void) header.len > sizeof(header)) { nvram_len = header.len; if (nvram_len >= NVRAM_SPACE) {
pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n",
}pr_err("nvram on flash (%zu bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n", header.len, NVRAM_SPACE); nvram_len = NVRAM_SPACE - 1;
On Sun, Sep 29, 2019 at 12:39:05PM -0700, Florian Fainelli wrote:
On 9/29/2019 10:30 AM, Sasha Levin wrote:
From: Florian Fainelli f.fainelli@gmail.com
[ Upstream commit feb4eb060c3aecc3c5076bebe699cd09f1133c41 ]
When building on a 64-bit host, we will get warnings like those:
drivers/firmware/broadcom/bcm47xx_nvram.c:103:3: note: in expansion of macro 'pr_err' pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n", ^~~~~~ drivers/firmware/broadcom/bcm47xx_nvram.c:103:28: note: format string is defined here pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n", ~^ %li
Use %zu instead for that purpose.
This is not a fix that should be backported as it was done only to allow the driver to the made buildable with COMPILE_TEST. Please drop it from your auto-selection.
Now dropped, thank you!
From: Anson Huang Anson.Huang@nxp.com
[ Upstream commit 6fd4fe9b496d9ba3382992ff4fde3871d1b6f63d ]
The RTC IRQ is requested before the struct rtc_device is allocated, this may lead to a NULL pointer dereference in IRQ handler.
To fix this issue, allocating the rtc_device struct before requesting the RTC IRQ using devm_rtc_allocate_device, and use rtc_register_device to register the RTC device.
Signed-off-by: Anson Huang Anson.Huang@nxp.com Reviewed-by: Dong Aisheng aisheng.dong@nxp.com Link: https://lore.kernel.org/r/20190716071858.36750-1-Anson.Huang@nxp.com Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/rtc/rtc-snvs.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c index 7ee673a25fd0a..4f9a107a04277 100644 --- a/drivers/rtc/rtc-snvs.c +++ b/drivers/rtc/rtc-snvs.c @@ -279,6 +279,10 @@ static int snvs_rtc_probe(struct platform_device *pdev) if (!data) return -ENOMEM;
+ data->rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(data->rtc)) + return PTR_ERR(data->rtc); + data->regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "regmap");
if (IS_ERR(data->regmap)) { @@ -343,10 +347,9 @@ static int snvs_rtc_probe(struct platform_device *pdev) goto error_rtc_device_register; }
- data->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, - &snvs_rtc_ops, THIS_MODULE); - if (IS_ERR(data->rtc)) { - ret = PTR_ERR(data->rtc); + data->rtc->ops = &snvs_rtc_ops; + ret = rtc_register_device(data->rtc); + if (ret) { dev_err(&pdev->dev, "failed to register rtc: %d\n", ret); goto error_rtc_device_register; }
From: Biwen Li biwen.li@nxp.com
[ Upstream commit 7ef66122bdb3b839e9f51b76d7e600b6e21ef648 ]
Issue: - # hwclock -w hwclock: RTC_SET_TIME: Invalid argument
Why: - Relative commit: 8b9f9d4dc511 ("regmap: verify if register is writeable before writing operations"), this patch will always check for unwritable registers, it will compare reg with max_register in regmap_writeable.
- The pcf85363/pcf85263 has the capability of address wrapping which means if you access an address outside the allowed range (0x00-0x2f) hardware actually wraps the access to a lower address. The rtc-pcf85363 driver will use this feature to configure the time and execute 2 actions in the same i2c write operation (stopping the clock and configure the time). However the driver has also configured the `regmap maxregister` protection mechanism that will block accessing addresses outside valid range (0x00-0x2f).
How: - Split of writing regs to two parts, first part writes control registers about stop_enable and resets, second part writes RTC time and date registers.
Signed-off-by: Biwen Li biwen.li@nxp.com Link: https://lore.kernel.org/r/20190829021418.4607-1-biwen.li@nxp.com Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/rtc/rtc-pcf85363.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/rtc/rtc-pcf85363.c b/drivers/rtc/rtc-pcf85363.c index a075e77617dcb..3450d615974d5 100644 --- a/drivers/rtc/rtc-pcf85363.c +++ b/drivers/rtc/rtc-pcf85363.c @@ -166,7 +166,12 @@ static int pcf85363_rtc_set_time(struct device *dev, struct rtc_time *tm) buf[DT_YEARS] = bin2bcd(tm->tm_year % 100);
ret = regmap_bulk_write(pcf85363->regmap, CTRL_STOP_EN, - tmp, sizeof(tmp)); + tmp, 2); + if (ret) + return ret; + + ret = regmap_bulk_write(pcf85363->regmap, DT_100THS, + buf, sizeof(tmp) - 2); if (ret) return ret;
From: Romain Izard romain.izard.pro@gmail.com
[ Upstream commit f1b937cc86bedf94dbc3478c2c0dc79471081fff ]
With the introduction of the HWMON compatibility layer to the power supply framework in Linux 5.3, all power supply devices' names can be used directly to create HWMON devices with the same names.
But HWMON has rules on allowable names that are different from those used in the power supply framework. The dash character is forbidden, as it is used by the libsensors library in userspace as a separator, whereas this character is used in the device names in more than half of the existing power supply drivers. This last case is consistent with the typical naming usage with MFD and Device Tree.
This leads to warnings in the kernel log, with the format:
power_supply gpio-charger: hwmon: \ 'gpio-charger' is not a valid name attribute, please fix
Add a protection to power_supply_add_hwmon_sysfs() that replaces any dash in the device name with an underscore when registering with the HWMON framework. Other forbidden characters (star, slash, space, tab, newline) are not replaced, as they are not in common use.
Fixes: e67d4dfc9ff1 ("power: supply: Add HWMON compatibility layer") Signed-off-by: Romain Izard romain.izard.pro@gmail.com Reviewed-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sebastian Reichel sebastian.reichel@collabora.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/power/supply/power_supply_hwmon.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/power/supply/power_supply_hwmon.c b/drivers/power/supply/power_supply_hwmon.c index 51fe60440d125..75cf861ba492d 100644 --- a/drivers/power/supply/power_supply_hwmon.c +++ b/drivers/power/supply/power_supply_hwmon.c @@ -284,6 +284,7 @@ int power_supply_add_hwmon_sysfs(struct power_supply *psy) struct device *dev = &psy->dev; struct device *hwmon; int ret, i; + const char *name;
if (!devres_open_group(dev, power_supply_add_hwmon_sysfs, GFP_KERNEL)) @@ -334,7 +335,19 @@ int power_supply_add_hwmon_sysfs(struct power_supply *psy) } }
- hwmon = devm_hwmon_device_register_with_info(dev, psy->desc->name, + name = psy->desc->name; + if (strchr(name, '-')) { + char *new_name; + + new_name = devm_kstrdup(dev, name, GFP_KERNEL); + if (!new_name) { + ret = -ENOMEM; + goto error; + } + strreplace(new_name, '-', '_'); + name = new_name; + } + hwmon = devm_hwmon_device_register_with_info(dev, name, psyhw, &power_supply_hwmon_chip_info, NULL);
From: Stephen Smalley sds@tycho.nsa.gov
[ Upstream commit 169ce0c081cd85f78388bb6c1638c1ad7b81bde7 ]
We need to use selinux_cred() to fetch the SELinux cred blob instead of directly using current->security or current_security(). There were a couple of lingering uses of current_security() in the SELinux code that were apparently missed during the earlier conversions. IIUC, this would only manifest as a bug if multiple security modules including SELinux are enabled and SELinux is not first in the lsm order. After this change, there appear to be no other users of current_security() in-tree; perhaps we should remove it altogether.
Fixes: bbd3662a8348 ("Infrastructure management of the cred security blob") Signed-off-by: Stephen Smalley sds@tycho.nsa.gov Acked-by: Casey Schaufler casey@schaufler-ca.com Reviewed-by: James Morris jamorris@linux.microsoft.com Signed-off-by: Paul Moore paul@paul-moore.com Signed-off-by: Sasha Levin sashal@kernel.org --- security/selinux/hooks.c | 2 +- security/selinux/include/objsec.h | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 74dd46de01b6a..e755174647866 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3403,7 +3403,7 @@ static int selinux_inode_copy_up_xattr(const char *name) static int selinux_kernfs_init_security(struct kernfs_node *kn_dir, struct kernfs_node *kn) { - const struct task_security_struct *tsec = current_security(); + const struct task_security_struct *tsec = selinux_cred(current_cred()); u32 parent_sid, newsid, clen; int rc; char *context; diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 91c5395dd20c2..586b7abd0aa73 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -37,16 +37,6 @@ struct task_security_struct { u32 sockcreate_sid; /* fscreate SID */ };
-/* - * get the subjective security ID of the current task - */ -static inline u32 current_sid(void) -{ - const struct task_security_struct *tsec = current_security(); - - return tsec->sid; -} - enum label_initialized { LABEL_INVALID, /* invalid or not initialized */ LABEL_INITIALIZED, /* initialized */ @@ -185,4 +175,14 @@ static inline struct ipc_security_struct *selinux_ipc( return ipc->security + selinux_blob_sizes.lbs_ipc; }
+/* + * get the subjective security ID of the current task + */ +static inline u32 current_sid(void) +{ + const struct task_security_struct *tsec = selinux_cred(current_cred()); + + return tsec->sid; +} + #endif /* _SELINUX_OBJSEC_H_ */
From: Krzysztof Wilczynski kw@linux.com
[ Upstream commit 7f1c62c443a453deb6eb3515e3c05650ffe0dcf0 ]
Do not use printk_ratelimit() in drivers/pci/pci.c as it shares the rate limiting state with all other callers to the printk_ratelimit().
Add pci_info_ratelimited() (similar to pci_notice_ratelimited() added in the commit a88a7b3eb076 ("vfio: Use dev_printk() when possible")) and use it instead of printk_ratelimit() + pci_info().
Link: https://lore.kernel.org/r/20190825224616.8021-1-kw@linux.com Signed-off-by: Krzysztof Wilczynski kw@linux.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/pci.c | 4 ++-- include/linux/pci.h | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 1b27b5af3d552..1f17da3dfeac5 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -890,8 +890,8 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state)
pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK); - if (dev->current_state != state && printk_ratelimit()) - pci_info(dev, "Refused to change power state, currently in D%d\n", + if (dev->current_state != state) + pci_info_ratelimited(dev, "Refused to change power state, currently in D%d\n", dev->current_state);
/* diff --git a/include/linux/pci.h b/include/linux/pci.h index 82e4cd1b7ac3c..ac8a6c4e17923 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -2435,4 +2435,7 @@ void pci_uevent_ers(struct pci_dev *pdev, enum pci_ers_result err_type); #define pci_notice_ratelimited(pdev, fmt, arg...) \ dev_notice_ratelimited(&(pdev)->dev, fmt, ##arg)
+#define pci_info_ratelimited(pdev, fmt, arg...) \ + dev_info_ratelimited(&(pdev)->dev, fmt, ##arg) + #endif /* LINUX_PCI_H */
From: Joao Moreno mail@joaomoreno.com
[ Upstream commit aec256d0ecd561036f188dbc8fa7924c47a9edfd ]
This fixes an issue in which key down events for function keys would be repeatedly emitted even after the user has raised the physical key. For example, the driver fails to emit the F5 key up event when going through the following steps: - fnmode=1: hold FN, hold F5, release FN, release F5 - fnmode=2: hold F5, hold FN, release F5, release FN
The repeated F5 key down events can be easily verified using xev.
Signed-off-by: Joao Moreno mail@joaomoreno.com Co-developed-by: Benjamin Tissoires benjamin.tissoires@redhat.com Signed-off-by: Benjamin Tissoires benjamin.tissoires@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/hid-apple.c | 49 +++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 21 deletions(-)
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 81df62f48c4c3..6ac8becc2372e 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -54,7 +54,6 @@ MODULE_PARM_DESC(swap_opt_cmd, "Swap the Option ("Alt") and Command ("Flag") struct apple_sc { unsigned long quirks; unsigned int fn_on; - DECLARE_BITMAP(pressed_fn, KEY_CNT); DECLARE_BITMAP(pressed_numlock, KEY_CNT); };
@@ -181,6 +180,8 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, { struct apple_sc *asc = hid_get_drvdata(hid); const struct apple_key_translation *trans, *table; + bool do_translate; + u16 code = 0;
if (usage->code == KEY_FN) { asc->fn_on = !!value; @@ -189,8 +190,6 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, }
if (fnmode) { - int do_translate; - if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI && hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) table = macbookair_fn_keys; @@ -202,25 +201,33 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, trans = apple_find_translation (table, usage->code);
if (trans) { - if (test_bit(usage->code, asc->pressed_fn)) - do_translate = 1; - else if (trans->flags & APPLE_FLAG_FKEY) - do_translate = (fnmode == 2 && asc->fn_on) || - (fnmode == 1 && !asc->fn_on); - else - do_translate = asc->fn_on; - - if (do_translate) { - if (value) - set_bit(usage->code, asc->pressed_fn); - else - clear_bit(usage->code, asc->pressed_fn); - - input_event(input, usage->type, trans->to, - value); - - return 1; + if (test_bit(trans->from, input->key)) + code = trans->from; + else if (test_bit(trans->to, input->key)) + code = trans->to; + + if (!code) { + if (trans->flags & APPLE_FLAG_FKEY) { + switch (fnmode) { + case 1: + do_translate = !asc->fn_on; + break; + case 2: + do_translate = asc->fn_on; + break; + default: + /* should never happen */ + do_translate = false; + } + } else { + do_translate = asc->fn_on; + } + + code = do_translate ? trans->to : trans->from; } + + input_event(input, usage->type, code, value); + return 1; }
if (asc->quirks & APPLE_NUMLOCK_EMULATION &&
From: Thierry Reding treding@nvidia.com
[ Upstream commit 0e3ff0ac5f71bdb6be2a698de0ed0c7e6e738269 ]
regulator_get_optional() can fail for a number of reasons besides probe deferral. It can for example return -ENOMEM if it runs out of memory as it tries to allocate data structures. Propagating only -EPROBE_DEFER is problematic because it results in these legitimately fatal errors being treated as "regulator not specified in DT".
What we really want is to ignore the optional regulators only if they have not been specified in DT. regulator_get_optional() returns -ENODEV in this case, so that's the special case that we need to handle. So we propagate all errors, except -ENODEV, so that real failures will still cause the driver to fail probe.
Tested-by: Heiko Stuebner heiko@sntech.de Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: Andrew Murray andrew.murray@arm.com Reviewed-by: Heiko Stuebner heiko@sntech.de Acked-by: Shawn Lin shawn.lin@rock-chips.com Cc: Shawn Lin shawn.lin@rock-chips.com Cc: Heiko Stuebner heiko@sntech.de Cc: linux-rockchip@lists.infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/pcie-rockchip-host.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c index 8d20f1793a618..ef8e677ce9d11 100644 --- a/drivers/pci/controller/pcie-rockchip-host.c +++ b/drivers/pci/controller/pcie-rockchip-host.c @@ -608,29 +608,29 @@ static int rockchip_pcie_parse_host_dt(struct rockchip_pcie *rockchip)
rockchip->vpcie12v = devm_regulator_get_optional(dev, "vpcie12v"); if (IS_ERR(rockchip->vpcie12v)) { - if (PTR_ERR(rockchip->vpcie12v) == -EPROBE_DEFER) - return -EPROBE_DEFER; + if (PTR_ERR(rockchip->vpcie12v) != -ENODEV) + return PTR_ERR(rockchip->vpcie12v); dev_info(dev, "no vpcie12v regulator found\n"); }
rockchip->vpcie3v3 = devm_regulator_get_optional(dev, "vpcie3v3"); if (IS_ERR(rockchip->vpcie3v3)) { - if (PTR_ERR(rockchip->vpcie3v3) == -EPROBE_DEFER) - return -EPROBE_DEFER; + if (PTR_ERR(rockchip->vpcie3v3) != -ENODEV) + return PTR_ERR(rockchip->vpcie3v3); dev_info(dev, "no vpcie3v3 regulator found\n"); }
rockchip->vpcie1v8 = devm_regulator_get_optional(dev, "vpcie1v8"); if (IS_ERR(rockchip->vpcie1v8)) { - if (PTR_ERR(rockchip->vpcie1v8) == -EPROBE_DEFER) - return -EPROBE_DEFER; + if (PTR_ERR(rockchip->vpcie1v8) != -ENODEV) + return PTR_ERR(rockchip->vpcie1v8); dev_info(dev, "no vpcie1v8 regulator found\n"); }
rockchip->vpcie0v9 = devm_regulator_get_optional(dev, "vpcie0v9"); if (IS_ERR(rockchip->vpcie0v9)) { - if (PTR_ERR(rockchip->vpcie0v9) == -EPROBE_DEFER) - return -EPROBE_DEFER; + if (PTR_ERR(rockchip->vpcie0v9) != -ENODEV) + return PTR_ERR(rockchip->vpcie0v9); dev_info(dev, "no vpcie0v9 regulator found\n"); }
From: Thierry Reding treding@nvidia.com
[ Upstream commit 8f9e1641ba445437095411d9fda2324121110d5d ]
regulator_get_optional() can fail for a number of reasons besides probe deferral. It can for example return -ENOMEM if it runs out of memory as it tries to allocate data structures. Propagating only -EPROBE_DEFER is problematic because it results in these legitimately fatal errors being treated as "regulator not specified in DT".
What we really want is to ignore the optional regulators only if they have not been specified in DT. regulator_get_optional() returns -ENODEV in this case, so that's the special case that we need to handle. So we propagate all errors, except -ENODEV, so that real failures will still cause the driver to fail probe.
Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: Andrew Murray andrew.murray@arm.com Cc: Shawn Guo shawn.guo@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/dwc/pcie-histb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-histb.c b/drivers/pci/controller/dwc/pcie-histb.c index 954bc2b74bbcd..811b5c6d62eae 100644 --- a/drivers/pci/controller/dwc/pcie-histb.c +++ b/drivers/pci/controller/dwc/pcie-histb.c @@ -340,8 +340,8 @@ static int histb_pcie_probe(struct platform_device *pdev)
hipcie->vpcie = devm_regulator_get_optional(dev, "vpcie"); if (IS_ERR(hipcie->vpcie)) { - if (PTR_ERR(hipcie->vpcie) == -EPROBE_DEFER) - return -EPROBE_DEFER; + if (PTR_ERR(hipcie->vpcie) != -ENODEV) + return PTR_ERR(hipcie->vpcie); hipcie->vpcie = NULL; }
From: Thierry Reding treding@nvidia.com
[ Upstream commit 2170a09fb4b0f66e06e5bcdcbc98c9ccbf353650 ]
regulator_get_optional() can fail for a number of reasons besides probe deferral. It can for example return -ENOMEM if it runs out of memory as it tries to allocate data structures. Propagating only -EPROBE_DEFER is problematic because it results in these legitimately fatal errors being treated as "regulator not specified in DT".
What we really want is to ignore the optional regulators only if they have not been specified in DT. regulator_get_optional() returns -ENODEV in this case, so that's the special case that we need to handle. So we propagate all errors, except -ENODEV, so that real failures will still cause the driver to fail probe.
Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: Andrew Murray andrew.murray@arm.com Cc: Richard Zhu hongxing.zhu@nxp.com Cc: Lucas Stach l.stach@pengutronix.de Cc: Shawn Guo shawnguo@kernel.org Cc: Sascha Hauer s.hauer@pengutronix.de Cc: Fabio Estevam festevam@gmail.com Cc: kernel@pengutronix.de Cc: linux-imx@nxp.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/dwc/pci-imx6.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index 9b5cb5b703890..aabf22eaa6b91 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -1173,8 +1173,8 @@ static int imx6_pcie_probe(struct platform_device *pdev)
imx6_pcie->vpcie = devm_regulator_get_optional(&pdev->dev, "vpcie"); if (IS_ERR(imx6_pcie->vpcie)) { - if (PTR_ERR(imx6_pcie->vpcie) == -EPROBE_DEFER) - return -EPROBE_DEFER; + if (PTR_ERR(imx6_pcie->vpcie) != -ENODEV) + return PTR_ERR(imx6_pcie->vpcie); imx6_pcie->vpcie = NULL; }
From: Thierry Reding treding@nvidia.com
[ Upstream commit ddd6960087d4b45759434146d681a94bbb1c54ad ]
devm_of_phy_get() can fail for a number of reasons besides probe deferral. It can for example return -ENOMEM if it runs out of memory as it tries to allocate devres structures. Propagating only -EPROBE_DEFER is problematic because it results in these legitimately fatal errors being treated as "PHY not specified in DT".
What we really want is to ignore the optional PHYs only if they have not been specified in DT. devm_of_phy_get() returns -ENODEV in this case, so that's the special case that we need to handle. So we propagate all errors, except -ENODEV, so that real failures will still cause the driver to fail probe.
Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: Andrew Murray andrew.murray@arm.com Cc: Jingoo Han jingoohan1@gmail.com Cc: Kukjin Kim kgene@kernel.org Cc: Krzysztof Kozlowski krzk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/dwc/pci-exynos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controller/dwc/pci-exynos.c index cee5f2f590e2d..14a6ba4067fbe 100644 --- a/drivers/pci/controller/dwc/pci-exynos.c +++ b/drivers/pci/controller/dwc/pci-exynos.c @@ -465,7 +465,7 @@ static int __init exynos_pcie_probe(struct platform_device *pdev)
ep->phy = devm_of_phy_get(dev, np, NULL); if (IS_ERR(ep->phy)) { - if (PTR_ERR(ep->phy) == -EPROBE_DEFER) + if (PTR_ERR(ep->phy) != -ENODEV) return PTR_ERR(ep->phy);
ep->phy = NULL;
From: Jia-Ju Bai baijiaju1990@gmail.com
[ Upstream commit 3f4287e7d98a2954f20bf96c567fdffcd2b63eb9 ]
In smack_socket_sock_rcv_skb(), there is an if statement on line 3920 to check whether skb is NULL: if (skb && skb->secmark != 0)
This check indicates skb can be NULL in some cases.
But on lines 3931 and 3932, skb is used: ad.a.u.net->netif = skb->skb_iif; ipv6_skb_to_auditdata(skb, &ad.a, NULL);
Thus, possible null-pointer dereferences may occur when skb is NULL.
To fix these possible bugs, an if statement is added to check skb.
These bugs are found by a static analysis tool STCheck written by us.
Signed-off-by: Jia-Ju Bai baijiaju1990@gmail.com Signed-off-by: Casey Schaufler casey@schaufler-ca.com Signed-off-by: Sasha Levin sashal@kernel.org --- security/smack/smack_lsm.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 4c5e5a438f8bd..5c9fc8ba6e572 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -3925,6 +3925,8 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) skp = smack_ipv6host_label(&sadd); if (skp == NULL) skp = smack_net_ambient; + if (skb == NULL) + break; #ifdef CONFIG_AUDIT smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); ad.a.u.net->family = family;
From: Krzysztof Wilczynski kw@linux.com
[ Upstream commit 8050f3f6645ae0f7e4c1304593f6f7eb2ee7d85c ]
Move the static keyword to the front of declarations of pci_regs_behavior[] and pcie_cap_regs_behavior[], which resolves compiler warnings when building with "W=1":
drivers/pci/pci-bridge-emul.c:41:1: warning: ‘static’ is not at beginning of declaration [-Wold-style-declaration] const static struct pci_bridge_reg_behavior pci_regs_behavior[] = { ^ drivers/pci/pci-bridge-emul.c:176:1: warning: ‘static’ is not at beginning of declaration [-Wold-style-declaration] const static struct pci_bridge_reg_behavior pcie_cap_regs_behavior[] = { ^
Link: https://lore.kernel.org/r/20190826151436.4672-1-kw@linux.com Link: https://lore.kernel.org/r/20190828131733.5817-1-kw@linux.com Signed-off-by: Krzysztof Wilczynski kw@linux.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Acked-by: Thomas Petazzoni thomas.petazzoni@bootlin.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/pci-bridge-emul.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/pci-bridge-emul.c b/drivers/pci/pci-bridge-emul.c index 06083b86d4f45..5fd90105510d9 100644 --- a/drivers/pci/pci-bridge-emul.c +++ b/drivers/pci/pci-bridge-emul.c @@ -38,7 +38,7 @@ struct pci_bridge_reg_behavior { u32 rsvd; };
-const static struct pci_bridge_reg_behavior pci_regs_behavior[] = { +static const struct pci_bridge_reg_behavior pci_regs_behavior[] = { [PCI_VENDOR_ID / 4] = { .ro = ~0 }, [PCI_COMMAND / 4] = { .rw = (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | @@ -173,7 +173,7 @@ const static struct pci_bridge_reg_behavior pci_regs_behavior[] = { }, };
-const static struct pci_bridge_reg_behavior pcie_cap_regs_behavior[] = { +static const struct pci_bridge_reg_behavior pcie_cap_regs_behavior[] = { [PCI_CAP_LIST_ID / 4] = { /* * Capability ID, Next Capability Pointer and
From: Nathan Chancellor natechancellor@gmail.com
[ Upstream commit b0fe66cf095016e0b238374c10ae366e1f087d11 ]
Currently, multi_v7_defconfig + CONFIG_FUNCTION_TRACER fails to build with clang:
arm-linux-gnueabi-ld: kernel/softirq.o: in function `_local_bh_enable': softirq.c:(.text+0x504): undefined reference to `mcount' arm-linux-gnueabi-ld: kernel/softirq.o: in function `__local_bh_enable_ip': softirq.c:(.text+0x58c): undefined reference to `mcount' arm-linux-gnueabi-ld: kernel/softirq.o: in function `do_softirq': softirq.c:(.text+0x6c8): undefined reference to `mcount' arm-linux-gnueabi-ld: kernel/softirq.o: in function `irq_enter': softirq.c:(.text+0x75c): undefined reference to `mcount' arm-linux-gnueabi-ld: kernel/softirq.o: in function `irq_exit': softirq.c:(.text+0x840): undefined reference to `mcount' arm-linux-gnueabi-ld: kernel/softirq.o:softirq.c:(.text+0xa50): more undefined references to `mcount' follow
clang can emit a working mcount symbol, __gnu_mcount_nc, when '-meabi gnu' is passed to it. Until r369147 in LLVM, this was broken and caused the kernel not to boot with '-pg' because the calling convention was not correct. Always build with '-meabi gnu' when using clang but ensure that '-pg' (which is added with CONFIG_FUNCTION_TRACER and its prereq CONFIG_HAVE_FUNCTION_TRACER) cannot be added with it unless this is fixed (which means using clang 10.0.0 and newer).
Link: https://github.com/ClangBuiltLinux/linux/issues/35 Link: https://bugs.llvm.org/show_bug.cgi?id=33845 Link: https://github.com/llvm/llvm-project/commit/16fa8b09702378bacfa3d07081afe6b3...
Reviewed-by: Matthias Kaehlcke mka@chromium.org Reviewed-by: Nick Desaulniers ndesaulniers@google.com Reviewed-by: Stefan Agner stefan@agner.ch Signed-off-by: Nathan Chancellor natechancellor@gmail.com Signed-off-by: Russell King rmk+kernel@armlinux.org.uk Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/Kconfig | 2 +- arch/arm/Makefile | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5e2c68e9dd6e2..b587a3b3939ab 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -82,7 +82,7 @@ config ARM select HAVE_FAST_GUP if ARM_LPAE select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL select HAVE_FUNCTION_GRAPH_TRACER if !THUMB2_KERNEL && !CC_IS_CLANG - select HAVE_FUNCTION_TRACER if !XIP_KERNEL + select HAVE_FUNCTION_TRACER if !XIP_KERNEL && (CC_IS_GCC || CLANG_VERSION >= 100000) select HAVE_GCC_PLUGINS select HAVE_HW_BREAKPOINT if PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7) select HAVE_IDE if PCI || ISA || PCMCIA diff --git a/arch/arm/Makefile b/arch/arm/Makefile index c3624ca6c0bca..9b3d4deca9e4e 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -112,6 +112,10 @@ ifeq ($(CONFIG_ARM_UNWIND),y) CFLAGS_ABI +=-funwind-tables endif
+ifeq ($(CONFIG_CC_IS_CLANG),y) +CFLAGS_ABI += -meabi gnu +endif + # Accept old syntax despite ".syntax unified" AFLAGS_NOWARN :=$(call as-option,-Wa$(comma)-mno-warn-deprecated,-Wa$(comma)-W)
From: Mike Rapoport mike.rapoport@gmail.com
[ Upstream commit 00d2ec1e6bd82c0538e6dd3e4a4040de93ba4fef ]
The calculation of memblock_limit in adjust_lowmem_bounds() assumes that bank 0 starts from a PMD-aligned address. However, the beginning of the first bank may be NOMAP memory and the start of usable memory will be not aligned to PMD boundary. In such case the memblock_limit will be set to the end of the NOMAP region, which will prevent any memblock allocations.
Mark the region between the end of the NOMAP area and the next PMD-aligned address as NOMAP as well, so that the usable memory will start at PMD-aligned address.
Signed-off-by: Mike Rapoport rppt@linux.ibm.com Signed-off-by: Russell King rmk+kernel@armlinux.org.uk Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mm/mmu.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index d9a0038774a6d..d5e0b908f0bad 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -1177,6 +1177,22 @@ void __init adjust_lowmem_bounds(void) */ vmalloc_limit = (u64)(uintptr_t)vmalloc_min - PAGE_OFFSET + PHYS_OFFSET;
+ /* + * The first usable region must be PMD aligned. Mark its start + * as MEMBLOCK_NOMAP if it isn't + */ + for_each_memblock(memory, reg) { + if (!memblock_is_nomap(reg)) { + if (!IS_ALIGNED(reg->base, PMD_SIZE)) { + phys_addr_t len; + + len = round_up(reg->base, PMD_SIZE) - reg->base; + memblock_mark_nomap(reg->base, len); + } + break; + } + } + for_each_memblock(memory, reg) { phys_addr_t block_start = reg->base; phys_addr_t block_end = reg->base + reg->size;
From: Jon Hunter jonathanh@nvidia.com
[ Upstream commit 8ebf15e9c869e764b3aab4928938ee68c0e2bd6d ]
Commit acc8abcb2a9c ("i2c: tegra: Add suspend-resume support") added suspend support for the Tegra I2C driver and following this change on Tegra30 the following WARNING is seen on entering suspend ...
WARNING: CPU: 2 PID: 689 at /dvs/git/dirty/git-master_l4t-upstream/kernel/drivers/i2c/i2c-core.h:54 __i2c_transfer+0x35c/0x70c i2c i2c-4: Transfer while suspended Modules linked in: brcmfmac brcmutil CPU: 2 PID: 689 Comm: rtcwake Not tainted 5.3.0-rc7-g089cf7f6ecb2 #1 Hardware name: NVIDIA Tegra SoC (Flattened Device Tree) [<c0112264>] (unwind_backtrace) from [<c010ca94>] (show_stack+0x10/0x14) [<c010ca94>] (show_stack) from [<c0a77024>] (dump_stack+0xb4/0xc8) [<c0a77024>] (dump_stack) from [<c0124198>] (__warn+0xe0/0xf8) [<c0124198>] (__warn) from [<c01241f8>] (warn_slowpath_fmt+0x48/0x6c) [<c01241f8>] (warn_slowpath_fmt) from [<c06f6c40>] (__i2c_transfer+0x35c/0x70c) [<c06f6c40>] (__i2c_transfer) from [<c06f7048>] (i2c_transfer+0x58/0xf4) [<c06f7048>] (i2c_transfer) from [<c06f7130>] (i2c_transfer_buffer_flags+0x4c/0x70) [<c06f7130>] (i2c_transfer_buffer_flags) from [<c05bee78>] (regmap_i2c_write+0x14/0x30) [<c05bee78>] (regmap_i2c_write) from [<c05b9cac>] (_regmap_raw_write_impl+0x35c/0x868) [<c05b9cac>] (_regmap_raw_write_impl) from [<c05b984c>] (_regmap_update_bits+0xe4/0xec) [<c05b984c>] (_regmap_update_bits) from [<c05bad04>] (regmap_update_bits_base+0x50/0x74) [<c05bad04>] (regmap_update_bits_base) from [<c04d453c>] (regulator_disable_regmap+0x44/0x54) [<c04d453c>] (regulator_disable_regmap) from [<c04cf9d4>] (_regulator_do_disable+0xf8/0x268) [<c04cf9d4>] (_regulator_do_disable) from [<c04d1694>] (_regulator_disable+0xf4/0x19c) [<c04d1694>] (_regulator_disable) from [<c04d1770>] (regulator_disable+0x34/0x64) [<c04d1770>] (regulator_disable) from [<c04d2310>] (regulator_bulk_disable+0x28/0xb4) [<c04d2310>] (regulator_bulk_disable) from [<c0495cd4>] (tegra_pcie_power_off+0x64/0xa8) [<c0495cd4>] (tegra_pcie_power_off) from [<c0495f74>] (tegra_pcie_pm_suspend+0x25c/0x3f4) [<c0495f74>] (tegra_pcie_pm_suspend) from [<c05af48c>] (dpm_run_callback+0x38/0x1d4) [<c05af48c>] (dpm_run_callback) from [<c05afe30>] (__device_suspend_noirq+0xc0/0x2b8) [<c05afe30>] (__device_suspend_noirq) from [<c05b1c24>] (dpm_noirq_suspend_devices+0x100/0x37c) [<c05b1c24>] (dpm_noirq_suspend_devices) from [<c05b1ebc>] (dpm_suspend_noirq+0x1c/0x48) [<c05b1ebc>] (dpm_suspend_noirq) from [<c017d2c0>] (suspend_devices_and_enter+0x1d0/0xa00) [<c017d2c0>] (suspend_devices_and_enter) from [<c017dd10>] (pm_suspend+0x220/0x74c) [<c017dd10>] (pm_suspend) from [<c017c2c8>] (state_store+0x6c/0xc8) [<c017c2c8>] (state_store) from [<c02ef398>] (kernfs_fop_write+0xe8/0x1c4) [<c02ef398>] (kernfs_fop_write) from [<c0271e38>] (__vfs_write+0x2c/0x1c4) [<c0271e38>] (__vfs_write) from [<c02748dc>] (vfs_write+0xa4/0x184) [<c02748dc>] (vfs_write) from [<c0274b7c>] (ksys_write+0x9c/0xdc) [<c0274b7c>] (ksys_write) from [<c0101000>] (ret_fast_syscall+0x0/0x54) Exception stack(0xe9f21fa8 to 0xe9f21ff0) 1fa0: 0000006c 004b2438 00000004 004b2438 00000004 00000000 1fc0: 0000006c 004b2438 004b1228 00000004 00000004 00000004 0049e78c 004b1228 1fe0: 00000004 be9809b8 b6f0bc0b b6e96206
The problem is that the Tegra PCIe driver indirectly uses I2C for controlling some regulators and the I2C driver is now being suspended before the PCIe driver causing the PCIe suspend to fail. The Tegra PCIe driver is suspended during the NOIRQ phase and this cannot be changed due to other dependencies. Therefore, we also need to move the suspend handling for the Tegra I2C driver to the NOIRQ phase as well.
In order to move the I2C suspend handling to the NOIRQ phase we also need to avoid calling pm_runtime_get/put() because per commit 1e2ef05bb8cf ("PM: Limit race conditions between runtime PM and system sleep (v2)") these cannot be called early in resume. The function tegra_i2c_init(), called during resume, calls pm_runtime_get/put() and so move these calls outside of tegra_i2c_init(), so this function can be used during the NOIRQ resume phase.
Fixes: acc8abcb2a9c ("i2c: tegra: Add suspend-resume support")
Signed-off-by: Jon Hunter jonathanh@nvidia.com Acked-by: Thierry Reding treding@nvidia.com Signed-off-by: Wolfram Sang wsa@the-dreams.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/busses/i2c-tegra.c | 40 +++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 18 deletions(-)
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 9fcb13beeb8f4..7a3291d91a5ee 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -713,12 +713,6 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev, bool clk_reinit) u32 tsu_thd; u8 tlow, thigh;
- err = pm_runtime_get_sync(i2c_dev->dev); - if (err < 0) { - dev_err(i2c_dev->dev, "runtime resume failed %d\n", err); - return err; - } - reset_control_assert(i2c_dev->rst); udelay(2); reset_control_deassert(i2c_dev->rst); @@ -772,7 +766,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev, bool clk_reinit) if (err) { dev_err(i2c_dev->dev, "failed changing clock rate: %d\n", err); - goto err; + return err; } }
@@ -787,23 +781,21 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev, bool clk_reinit)
err = tegra_i2c_flush_fifos(i2c_dev); if (err) - goto err; + return err;
if (i2c_dev->is_multimaster_mode && i2c_dev->hw->has_slcg_override_reg) i2c_writel(i2c_dev, I2C_MST_CORE_CLKEN_OVR, I2C_CLKEN_OVERRIDE);
err = tegra_i2c_wait_for_config_load(i2c_dev); if (err) - goto err; + return err;
if (i2c_dev->irq_disabled) { i2c_dev->irq_disabled = false; enable_irq(i2c_dev->irq); }
-err: - pm_runtime_put(i2c_dev->dev); - return err; + return 0; }
static int tegra_i2c_disable_packet_mode(struct tegra_i2c_dev *i2c_dev) @@ -1616,12 +1608,14 @@ static int tegra_i2c_probe(struct platform_device *pdev) }
pm_runtime_enable(&pdev->dev); - if (!pm_runtime_enabled(&pdev->dev)) { + if (!pm_runtime_enabled(&pdev->dev)) ret = tegra_i2c_runtime_resume(&pdev->dev); - if (ret < 0) { - dev_err(&pdev->dev, "runtime resume failed\n"); - goto unprepare_div_clk; - } + else + ret = pm_runtime_get_sync(i2c_dev->dev); + + if (ret < 0) { + dev_err(&pdev->dev, "runtime resume failed\n"); + goto unprepare_div_clk; }
if (i2c_dev->is_multimaster_mode) { @@ -1666,6 +1660,8 @@ static int tegra_i2c_probe(struct platform_device *pdev) if (ret) goto release_dma;
+ pm_runtime_put(&pdev->dev); + return 0;
release_dma: @@ -1726,17 +1722,25 @@ static int tegra_i2c_resume(struct device *dev) struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev); int err;
+ err = tegra_i2c_runtime_resume(dev); + if (err) + return err; + err = tegra_i2c_init(i2c_dev, false); if (err) return err;
+ err = tegra_i2c_runtime_suspend(dev); + if (err) + return err; + i2c_mark_adapter_resumed(&i2c_dev->adapter);
return 0; }
static const struct dev_pm_ops tegra_i2c_pm = { - SET_SYSTEM_SLEEP_PM_OPS(tegra_i2c_suspend, tegra_i2c_resume) + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(tegra_i2c_suspend, tegra_i2c_resume) SET_RUNTIME_PM_OPS(tegra_i2c_runtime_suspend, tegra_i2c_runtime_resume, NULL) };
From: Paolo Valente paolo.valente@linaro.org
[ Upstream commit 58494c980f40274c465ebfdece02d401def088bf ]
If equal to 0, the injection limit for a bfq_queue is pushed to 1 after a first sample of the total service time of the I/O requests of the queue is computed (to allow injection to start). Yet, because of a mistake in the branch that performs this action, the push may happen also in some other case. This commit fixes this issue.
Tested-by: Oleksandr Natalenko oleksandr@natalenko.name Signed-off-by: Paolo Valente paolo.valente@linaro.org Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/bfq-iosched.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c index b33be928d164f..70bcbd02edcb1 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -5809,12 +5809,14 @@ static void bfq_update_inject_limit(struct bfq_data *bfqd, */ if ((bfqq->last_serv_time_ns == 0 && bfqd->rq_in_driver == 1) || tot_time_ns < bfqq->last_serv_time_ns) { + if (bfqq->last_serv_time_ns == 0) { + /* + * Now we certainly have a base value: make sure we + * start trying injection. + */ + bfqq->inject_limit = max_t(unsigned int, 1, old_limit); + } bfqq->last_serv_time_ns = tot_time_ns; - /* - * Now we certainly have a base value: make sure we - * start trying injection. - */ - bfqq->inject_limit = max_t(unsigned int, 1, old_limit); } else if (!bfqd->rqs_injected && bfqd->rq_in_driver == 1) /* * No I/O injected and no request still in service in
From: OGAWA Hirofumi hirofumi@mail.parknet.co.jp
[ Upstream commit 07bfa4415ab607e459b69bd86aa7e7602ce10b4f ]
If userspace reads the buffer via blockdev while mounting, sb_getblk()+modify can race with buffer read via blockdev.
For example,
FS userspace bh = sb_getblk() modify bh->b_data read ll_rw_block(bh) fill bh->b_data by on-disk data /* lost modified data by FS */ set_buffer_uptodate(bh) set_buffer_uptodate(bh)
Userspace should not use the blockdev while mounting though, the udev seems to be already doing this. Although I think the udev should try to avoid this, workaround the race by small overhead.
Link: http://lkml.kernel.org/r/87pnk7l3sw.fsf_-_@mail.parknet.co.jp Signed-off-by: OGAWA Hirofumi hirofumi@mail.parknet.co.jp Reported-by: Jan Stancek jstancek@redhat.com Tested-by: Jan Stancek jstancek@redhat.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/fat/dir.c | 13 +++++++++++-- fs/fat/fatent.c | 3 +++ 2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/fs/fat/dir.c b/fs/fat/dir.c index 1bda2ab6745ba..814ad2c2ba808 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c @@ -1100,8 +1100,11 @@ static int fat_zeroed_cluster(struct inode *dir, sector_t blknr, int nr_used, err = -ENOMEM; goto error; } + /* Avoid race with userspace read via bdev */ + lock_buffer(bhs[n]); memset(bhs[n]->b_data, 0, sb->s_blocksize); set_buffer_uptodate(bhs[n]); + unlock_buffer(bhs[n]); mark_buffer_dirty_inode(bhs[n], dir);
n++; @@ -1158,6 +1161,8 @@ int fat_alloc_new_dir(struct inode *dir, struct timespec64 *ts) fat_time_unix2fat(sbi, ts, &time, &date, &time_cs);
de = (struct msdos_dir_entry *)bhs[0]->b_data; + /* Avoid race with userspace read via bdev */ + lock_buffer(bhs[0]); /* filling the new directory slots ("." and ".." entries) */ memcpy(de[0].name, MSDOS_DOT, MSDOS_NAME); memcpy(de[1].name, MSDOS_DOTDOT, MSDOS_NAME); @@ -1180,6 +1185,7 @@ int fat_alloc_new_dir(struct inode *dir, struct timespec64 *ts) de[0].size = de[1].size = 0; memset(de + 2, 0, sb->s_blocksize - 2 * sizeof(*de)); set_buffer_uptodate(bhs[0]); + unlock_buffer(bhs[0]); mark_buffer_dirty_inode(bhs[0], dir);
err = fat_zeroed_cluster(dir, blknr, 1, bhs, MAX_BUF_PER_PAGE); @@ -1237,11 +1243,14 @@ static int fat_add_new_entries(struct inode *dir, void *slots, int nr_slots,
/* fill the directory entry */ copy = min(size, sb->s_blocksize); + /* Avoid race with userspace read via bdev */ + lock_buffer(bhs[n]); memcpy(bhs[n]->b_data, slots, copy); - slots += copy; - size -= copy; set_buffer_uptodate(bhs[n]); + unlock_buffer(bhs[n]); mark_buffer_dirty_inode(bhs[n], dir); + slots += copy; + size -= copy; if (!size) break; n++; diff --git a/fs/fat/fatent.c b/fs/fat/fatent.c index 265983635f2be..3647c65a0f482 100644 --- a/fs/fat/fatent.c +++ b/fs/fat/fatent.c @@ -388,8 +388,11 @@ static int fat_mirror_bhs(struct super_block *sb, struct buffer_head **bhs, err = -ENOMEM; goto error; } + /* Avoid race with userspace read via bdev */ + lock_buffer(c_bh); memcpy(c_bh->b_data, bhs[n]->b_data, sb->s_blocksize); set_buffer_uptodate(c_bh); + unlock_buffer(c_bh); mark_buffer_dirty_inode(c_bh, sbi->fat_inode); if (sb->s_flags & SB_SYNCHRONOUS) err = sync_dirty_buffer(c_bh);
From: Jens Axboe axboe@kernel.dk
[ Upstream commit eb09b3cc464d2c3bbde9a6648603c8d599ea8582 ]
Anatoly reports that he gets the below warning when booting -git on a sparc64 box on debian unstable:
... [ 13.352975] aes_sparc64: Using sparc64 aes opcodes optimized AES implementation [ 13.428002] ------------[ cut here ]------------ [ 13.428081] WARNING: CPU: 21 PID: 586 at drivers/block/pktcdvd.c:2597 pkt_setup_dev+0x2e4/0x5a0 [pktcdvd] [ 13.428147] Attempt to register a non-SCSI queue [ 13.428184] Modules linked in: pktcdvd libdes cdrom aes_sparc64 n2_rng md5_sparc64 sha512_sparc64 rng_core sha256_sparc64 flash sha1_sparc64 ip_tables x_tables ipv6 crc_ccitt nf_defrag_ipv6 autofs4 ext4 crc16 mbcache jbd2 raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor xor async_tx raid6_pq raid1 raid0 multipath linear md_mod crc32c_sparc64 [ 13.428452] CPU: 21 PID: 586 Comm: pktsetup Not tainted 5.3.0-10169-g574cc4539762 #1234 [ 13.428507] Call Trace: [ 13.428542] [00000000004635c0] __warn+0xc0/0x100 [ 13.428582] [0000000000463634] warn_slowpath_fmt+0x34/0x60 [ 13.428626] [000000001045b244] pkt_setup_dev+0x2e4/0x5a0 [pktcdvd] [ 13.428674] [000000001045ccf4] pkt_ctl_ioctl+0x94/0x220 [pktcdvd] [ 13.428724] [00000000006b95c8] do_vfs_ioctl+0x628/0x6e0 [ 13.428764] [00000000006b96c8] ksys_ioctl+0x48/0x80 [ 13.428803] [00000000006b9714] sys_ioctl+0x14/0x40 [ 13.428847] [0000000000406294] linux_sparc_syscall+0x34/0x44 [ 13.428890] irq event stamp: 4181 [ 13.428924] hardirqs last enabled at (4189): [<00000000004e0a74>] console_unlock+0x634/0x6c0 [ 13.428984] hardirqs last disabled at (4196): [<00000000004e0540>] console_unlock+0x100/0x6c0 [ 13.429048] softirqs last enabled at (3978): [<0000000000b2e2d8>] __do_softirq+0x498/0x520 [ 13.429110] softirqs last disabled at (3967): [<000000000042cfb4>] do_softirq_own_stack+0x34/0x60 [ 13.429172] ---[ end trace 2220ca468f32967d ]--- [ 13.430018] pktcdvd: setup of pktcdvd device failed [ 13.455589] des_sparc64: Using sparc64 des opcodes optimized DES implementation [ 13.515334] camellia_sparc64: Using sparc64 camellia opcodes optimized CAMELLIA implementation [ 13.522856] pktcdvd: setup of pktcdvd device failed [ 13.529327] pktcdvd: setup of pktcdvd device failed [ 13.532932] pktcdvd: setup of pktcdvd device failed [ 13.536165] pktcdvd: setup of pktcdvd device failed [ 13.539372] pktcdvd: setup of pktcdvd device failed [ 13.542834] pktcdvd: setup of pktcdvd device failed [ 13.546536] pktcdvd: setup of pktcdvd device failed [ 15.431071] XFS (dm-0): Mounting V5 Filesystem ...
Apparently debian auto-attaches any cdrom like device to pktcdvd, which can lead to the above warning. There's really no reason to warn for this situation, kill it.
Reported-by: Anatoly Pugachev matorola@gmail.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/pktcdvd.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 024060165afa7..76457003f1406 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -2594,7 +2594,6 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev) if (ret) return ret; if (!blk_queue_scsi_passthrough(bdev_get_queue(bdev))) { - WARN_ONCE(true, "Attempt to register a non-SCSI queue\n"); blkdev_put(bdev, FMODE_READ | FMODE_NDELAY); return -EINVAL; }
From: David Howells dhowells@redhat.com
[ Upstream commit b54c64f7adeb241423cd46598f458b5486b0375e ]
In hypfs_fill_super(), if hypfs_create_update_file() fails, sbi->update_file is left holding an error number. This is passed to hypfs_kill_super() which doesn't check for this.
Fix this by not setting sbi->update_value until after we've checked for error.
Fixes: 24bbb1faf3f0 ("[PATCH] s390_hypfs filesystem") Signed-off-by: David Howells dhowells@redhat.com cc: Martin Schwidefsky schwidefsky@de.ibm.com cc: Heiko Carstens heiko.carstens@de.ibm.com cc: linux-s390@vger.kernel.org Signed-off-by: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/hypfs/inode.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index ccad1398abd40..b5cfcad953c2e 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c @@ -269,7 +269,7 @@ static int hypfs_show_options(struct seq_file *s, struct dentry *root) static int hypfs_fill_super(struct super_block *sb, void *data, int silent) { struct inode *root_inode; - struct dentry *root_dentry; + struct dentry *root_dentry, *update_file; int rc = 0; struct hypfs_sb_info *sbi;
@@ -300,9 +300,10 @@ static int hypfs_fill_super(struct super_block *sb, void *data, int silent) rc = hypfs_diag_create_files(root_dentry); if (rc) return rc; - sbi->update_file = hypfs_create_update_file(root_dentry); - if (IS_ERR(sbi->update_file)) - return PTR_ERR(sbi->update_file); + update_file = hypfs_create_update_file(root_dentry); + if (IS_ERR(update_file)) + return PTR_ERR(update_file); + sbi->update_file = update_file; hypfs_update_update(sb); pr_info("Hypervisor filesystem mounted\n"); return 0;
From: Youquan Song youquan.song@intel.com
[ Upstream commit 44460efe44e05eae2f21e57d06d542bbbb792e65 ]
If the CPU package has the less logical CPU than topo_max_cpus, but un-present CPU's punit_cpu_core will be initiated to 0 and they will be count to core 0
Like below, there are only 10 high priority cores (20 logical CPUs) in the CPU package, but it count to 27 logic CPUs.
./intel-speed-select base-freq info -l 0 | grep mask high-priority-cpu-mask:7f000179,f000179f
With the fix patch: ./intel-speed-select base-freq info -l 0 high-priority-cpu-mask:00000179,f000179f
Signed-off-by: Youquan Song youquan.song@intel.com Signed-off-by: Srinivas Pandruvada srinivas.pandruvada@linux.intel.com Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/power/x86/intel-speed-select/isst-config.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 91c5ad1685a15..a6b1487b5f0f6 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -402,6 +402,9 @@ void set_cpu_mask_from_punit_coremask(int cpu, unsigned long long core_mask, int j;
for (j = 0; j < topo_max_cpus; ++j) { + if (!CPU_ISSET_S(j, present_cpumask_size, present_cpumask)) + continue; + if (cpu_map[j].pkg_id == pkg_id && cpu_map[j].die_id == die_id && cpu_map[j].punit_cpu_core == i) {
From: Yunfeng Ye yeyunfeng@huawei.com
[ Upstream commit 24fbf7bad888767bed952f540ac963bc57e47e15 ]
There are two problems in sec_free_hw_sgl():
First, when sgl_current->next is valid, @hw_sgl will be freed in the first loop, but it free again after the loop.
Second, sgl_current and sgl_current->next_sgl is not match when dma_pool_free() is invoked, the third parameter should be the dma address of sgl_current, but sgl_current->next_sgl is the dma address of next chain, so use sgl_current->next_sgl is wrong.
Fix this by deleting the last dma_pool_free() in sec_free_hw_sgl(), modifying the condition for while loop, and matching the address for dma_pool_free().
Fixes: 915e4e8413da ("crypto: hisilicon - SEC security accelerator driver") Signed-off-by: Yunfeng Ye yeyunfeng@huawei.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/hisilicon/sec/sec_algs.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/crypto/hisilicon/sec/sec_algs.c b/drivers/crypto/hisilicon/sec/sec_algs.c index 02768af0dccdd..8c789b8671fc4 100644 --- a/drivers/crypto/hisilicon/sec/sec_algs.c +++ b/drivers/crypto/hisilicon/sec/sec_algs.c @@ -215,17 +215,18 @@ static void sec_free_hw_sgl(struct sec_hw_sgl *hw_sgl, dma_addr_t psec_sgl, struct sec_dev_info *info) { struct sec_hw_sgl *sgl_current, *sgl_next; + dma_addr_t sgl_next_dma;
- if (!hw_sgl) - return; sgl_current = hw_sgl; - while (sgl_current->next) { + while (sgl_current) { sgl_next = sgl_current->next; - dma_pool_free(info->hw_sgl_pool, sgl_current, - sgl_current->next_sgl); + sgl_next_dma = sgl_current->next_sgl; + + dma_pool_free(info->hw_sgl_pool, sgl_current, psec_sgl); + sgl_current = sgl_next; + psec_sgl = sgl_next_dma; } - dma_pool_free(info->hw_sgl_pool, hw_sgl, psec_sgl); }
static int sec_alg_skcipher_setkey(struct crypto_skcipher *tfm,
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 710ec38b0f633ab3e2581f07a73442d809e28ab0 ]
On kernels without CONFIG_MMU, we get a link error for the siw driver:
drivers/infiniband/sw/siw/siw_mem.o: In function `siw_umem_get': siw_mem.c:(.text+0x4c8): undefined reference to `can_do_mlock'
This is probably not the only driver that needs the function and could otherwise build correctly without CONFIG_MMU, so add a dummy variant that always returns false.
Link: http://lkml.kernel.org/r/20190909204201.931830-1-arnd@arndb.de Fixes: 2251334dcac9 ("rdma/siw: application buffer management") Signed-off-by: Arnd Bergmann arnd@arndb.de Suggested-by: Jason Gunthorpe jgg@mellanox.com Acked-by: Michal Hocko mhocko@suse.com Cc: Bernard Metzler bmt@zurich.ibm.com Cc: "Matthew Wilcox (Oracle)" willy@infradead.org Cc: "Kirill A. Shutemov" kirill.shutemov@linux.intel.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/mm.h | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/include/linux/mm.h b/include/linux/mm.h index 0334ca97c584d..fe4552e1c40b4 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1405,7 +1405,11 @@ extern void pagefault_out_of_memory(void);
extern void show_free_areas(unsigned int flags, nodemask_t *nodemask);
+#ifdef CONFIG_MMU extern bool can_do_mlock(void); +#else +static inline bool can_do_mlock(void) { return false; } +#endif extern int user_shm_lock(size_t, struct user_struct *); extern void user_shm_unlock(size_t, struct user_struct *);
From: Greg Thelen gthelen@google.com
[ Upstream commit 6279eb3dd7946c69346a3b98473ed13d3a44adb5 ]
Since 9e3596b0c653 ("kbuild: initramfs cleanup, set target from Kconfig") "make clean" leaves behind compressed initramfs images. Example:
$ make defconfig $ sed -i 's|CONFIG_INITRAMFS_SOURCE=""|CONFIG_INITRAMFS_SOURCE="/tmp/ir.cpio"|' .config $ make olddefconfig $ make -s $ make -s clean $ git clean -ndxf | grep initramfs Would remove usr/initramfs_data.cpio.gz
clean rules do not have CONFIG_* context so they do not know which compression format was used. Thus they don't know which files to delete.
Tell clean to delete all possible compression formats.
Once patched usr/initramfs_data.cpio.gz and friends are deleted by "make clean".
Link: http://lkml.kernel.org/r/20190722063251.55541-1-gthelen@google.com Fixes: 9e3596b0c653 ("kbuild: initramfs cleanup, set target from Kconfig") Signed-off-by: Greg Thelen gthelen@google.com Cc: Nicholas Piggin npiggin@gmail.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- usr/Makefile | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/usr/Makefile b/usr/Makefile index 6a89eb019275b..e6f7cb2f81db4 100644 --- a/usr/Makefile +++ b/usr/Makefile @@ -11,6 +11,9 @@ datafile_y = initramfs_data.cpio$(suffix_y) datafile_d_y = .$(datafile_y).d AFLAGS_initramfs_data.o += -DINITRAMFS_IMAGE="usr/$(datafile_y)"
+# clean rules do not have CONFIG_INITRAMFS_COMPRESSION. So clean up after all +# possible compression formats. +clean-files += initramfs_data.cpio*
# Generate builtin.o based on initramfs_data.o obj-$(CONFIG_BLK_DEV_INITRD) := initramfs_data.o
From: Changwei Ge gechangwei@live.cn
[ Upstream commit 0a3775e4f883912944481cf2ef36eb6383a9cc74 ]
There is a scenario causing ocfs2 umount hang when multiple hosts are rebooting at the same time.
NODE1 NODE2 NODE3 send unlock requset to NODE2 dies become recovery master recover NODE2 find NODE2 dead mark resource RECOVERING directly remove lock from grant list calculate usage but RECOVERING marked **miss the window of purging clear RECOVERING
To reproduce this issue, crash a host and then umount ocfs2 from another node.
To solve this, just let unlock progress wait for recovery done.
Link: http://lkml.kernel.org/r/1550124866-20367-1-git-send-email-gechangwei@live.c... Signed-off-by: Changwei Ge gechangwei@live.cn Reviewed-by: Joseph Qi joseph.qi@linux.alibaba.com Cc: Mark Fasheh mark@fasheh.com Cc: Joel Becker jlbec@evilplan.org Cc: Junxiao Bi junxiao.bi@oracle.com Cc: Changwei Ge gechangwei@live.cn Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ocfs2/dlm/dlmunlock.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/fs/ocfs2/dlm/dlmunlock.c b/fs/ocfs2/dlm/dlmunlock.c index e78657742bd89..3883633e82eb9 100644 --- a/fs/ocfs2/dlm/dlmunlock.c +++ b/fs/ocfs2/dlm/dlmunlock.c @@ -90,7 +90,8 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm, enum dlm_status status; int actions = 0; int in_use; - u8 owner; + u8 owner; + int recovery_wait = 0;
mlog(0, "master_node = %d, valblk = %d\n", master_node, flags & LKM_VALBLK); @@ -193,9 +194,12 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm, } if (flags & LKM_CANCEL) lock->cancel_pending = 0; - else - lock->unlock_pending = 0; - + else { + if (!lock->unlock_pending) + recovery_wait = 1; + else + lock->unlock_pending = 0; + } }
/* get an extra ref on lock. if we are just switching @@ -229,6 +233,17 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm, spin_unlock(&res->spinlock); wake_up(&res->wq);
+ if (recovery_wait) { + spin_lock(&res->spinlock); + /* Unlock request will directly succeed after owner dies, + * and the lock is already removed from grant list. We have to + * wait for RECOVERING done or we miss the chance to purge it + * since the removement is much faster than RECOVERING proc. + */ + __dlm_wait_on_lockres_flags(res, DLM_LOCK_RES_RECOVERING); + spin_unlock(&res->spinlock); + } + /* let the caller's final dlm_lock_put handle the actual kfree */ if (actions & DLM_UNLOCK_FREE_LOCK) { /* this should always be coupled with list removal */
From: Nicolas Boichat drinkcat@chromium.org
[ Upstream commit b751c52bb587ae66f773b15204ef7a147467f4c7 ]
The current default value (400) is too low on many systems (e.g. some ARM64 platform takes up 1000+ entries).
syzbot uses 16000 as default value, and has proved to be enough on beefy configurations, so let's pick that value.
This consumes more RAM on boot (each entry is 160 bytes, so in total ~2.5MB of RAM), but the memory would later be freed (early_log is __initdata).
Link: http://lkml.kernel.org/r/20190730154027.101525-1-drinkcat@chromium.org Signed-off-by: Nicolas Boichat drinkcat@chromium.org Suggested-by: Dmitry Vyukov dvyukov@google.com Acked-by: Catalin Marinas catalin.marinas@arm.com Acked-by: Dmitry Vyukov dvyukov@google.com Cc: Masahiro Yamada yamada.masahiro@socionext.com Cc: Kees Cook keescook@chromium.org Cc: Petr Mladek pmladek@suse.com Cc: Thomas Gleixner tglx@linutronix.de Cc: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp Cc: Joe Lawrence joe.lawrence@redhat.com Cc: Uladzislau Rezki urezki@gmail.com Cc: Andy Shevchenko andriy.shevchenko@linux.intel.com Cc: Stephen Rothwell sfr@canb.auug.org.au Cc: Andrey Ryabinin aryabinin@virtuozzo.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- lib/Kconfig.debug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 5960e2980a8a0..4d39540011e2e 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -596,7 +596,7 @@ config DEBUG_KMEMLEAK_EARLY_LOG_SIZE int "Maximum kmemleak early log entries" depends on DEBUG_KMEMLEAK range 200 40000 - default 400 + default 16000 help Kmemleak must track all the memory allocations to avoid reporting false positives. Since memory may be allocated or
From: Alexandre Ghiti alex@ghiti.fr
[ Upstream commit e8d54b62c55ab6201de6d195fc2c276294c1f6ae ]
Do not offset mmap base address because of stack randomization if current task does not want randomization. Note that x86 already implements this behaviour.
Link: http://lkml.kernel.org/r/20190730055113.23635-4-alex@ghiti.fr Signed-off-by: Alexandre Ghiti alex@ghiti.fr Acked-by: Catalin Marinas catalin.marinas@arm.com Acked-by: Kees Cook keescook@chromium.org Reviewed-by: Christoph Hellwig hch@lst.de Reviewed-by: Luis Chamberlain mcgrof@kernel.org Cc: Albert Ou aou@eecs.berkeley.edu Cc: Alexander Viro viro@zeniv.linux.org.uk Cc: Christoph Hellwig hch@infradead.org Cc: James Hogan jhogan@kernel.org Cc: Palmer Dabbelt palmer@sifive.com Cc: Paul Burton paul.burton@mips.com Cc: Ralf Baechle ralf@linux-mips.org Cc: Russell King linux@armlinux.org.uk Cc: Will Deacon will.deacon@arm.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/mm/mmap.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c index b050641b51392..8dac7110f0cb5 100644 --- a/arch/arm64/mm/mmap.c +++ b/arch/arm64/mm/mmap.c @@ -54,7 +54,11 @@ unsigned long arch_mmap_rnd(void) static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack) { unsigned long gap = rlim_stack->rlim_cur; - unsigned long pad = (STACK_RND_MASK << PAGE_SHIFT) + stack_guard_gap; + unsigned long pad = stack_guard_gap; + + /* Account for stack randomization if necessary */ + if (current->flags & PF_RANDOMIZE) + pad += (STACK_RND_MASK << PAGE_SHIFT);
/* Values close to RLIM_INFINITY can overflow. */ if (gap + pad > gap)
From: Alexandre Ghiti alex@ghiti.fr
[ Upstream commit b1f61b5bde3a1f50392c97b4c8513d1b8efb1cf2 ]
This commit takes care of stack randomization and stack guard gap when computing mmap base address and checks if the task asked for randomization. This fixes the problem uncovered and not fixed for arm here: https://lkml.kernel.org/r/20170622200033.25714-1-riel@redhat.com
Link: http://lkml.kernel.org/r/20190730055113.23635-10-alex@ghiti.fr Signed-off-by: Alexandre Ghiti alex@ghiti.fr Acked-by: Kees Cook keescook@chromium.org Acked-by: Paul Burton paul.burton@mips.com Reviewed-by: Luis Chamberlain mcgrof@kernel.org Cc: Albert Ou aou@eecs.berkeley.edu Cc: Alexander Viro viro@zeniv.linux.org.uk Cc: Catalin Marinas catalin.marinas@arm.com Cc: Christoph Hellwig hch@infradead.org Cc: Christoph Hellwig hch@lst.de Cc: James Hogan jhogan@kernel.org Cc: Palmer Dabbelt palmer@sifive.com Cc: Ralf Baechle ralf@linux-mips.org Cc: Russell King linux@armlinux.org.uk Cc: Will Deacon will.deacon@arm.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/mm/mmap.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c index d79f2b4323187..f5c778113384b 100644 --- a/arch/mips/mm/mmap.c +++ b/arch/mips/mm/mmap.c @@ -21,8 +21,9 @@ unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */ EXPORT_SYMBOL(shm_align_mask);
/* gap between mmap and stack */ -#define MIN_GAP (128*1024*1024UL) -#define MAX_GAP ((TASK_SIZE)/6*5) +#define MIN_GAP (128*1024*1024UL) +#define MAX_GAP ((TASK_SIZE)/6*5) +#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12))
static int mmap_is_legacy(struct rlimit *rlim_stack) { @@ -38,6 +39,15 @@ static int mmap_is_legacy(struct rlimit *rlim_stack) static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack) { unsigned long gap = rlim_stack->rlim_cur; + unsigned long pad = stack_guard_gap; + + /* Account for stack randomization if necessary */ + if (current->flags & PF_RANDOMIZE) + pad += (STACK_RND_MASK << PAGE_SHIFT); + + /* Values close to RLIM_INFINITY can overflow. */ + if (gap + pad > gap) + gap += pad;
if (gap < MIN_GAP) gap = MIN_GAP;
From: Alexandre Ghiti alex@ghiti.fr
[ Upstream commit af0f4297286f13a75edf93677b1fb2fc16c412a7 ]
This commit takes care of stack randomization and stack guard gap when computing mmap base address and checks if the task asked for randomization. This fixes the problem uncovered and not fixed for arm here: https://lkml.kernel.org/r/20170622200033.25714-1-riel@redhat.com
Link: http://lkml.kernel.org/r/20190730055113.23635-7-alex@ghiti.fr Signed-off-by: Alexandre Ghiti alex@ghiti.fr Acked-by: Kees Cook keescook@chromium.org Reviewed-by: Luis Chamberlain mcgrof@kernel.org Cc: Albert Ou aou@eecs.berkeley.edu Cc: Alexander Viro viro@zeniv.linux.org.uk Cc: Catalin Marinas catalin.marinas@arm.com Cc: Christoph Hellwig hch@infradead.org Cc: Christoph Hellwig hch@lst.de Cc: James Hogan jhogan@kernel.org Cc: Palmer Dabbelt palmer@sifive.com Cc: Paul Burton paul.burton@mips.com Cc: Ralf Baechle ralf@linux-mips.org Cc: Russell King linux@armlinux.org.uk Cc: Will Deacon will.deacon@arm.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mm/mmap.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c index f866870db749c..bff3d00bda5be 100644 --- a/arch/arm/mm/mmap.c +++ b/arch/arm/mm/mmap.c @@ -18,8 +18,9 @@ (((pgoff)<<PAGE_SHIFT) & (SHMLBA-1)))
/* gap between mmap and stack */ -#define MIN_GAP (128*1024*1024UL) -#define MAX_GAP ((TASK_SIZE)/6*5) +#define MIN_GAP (128*1024*1024UL) +#define MAX_GAP ((TASK_SIZE)/6*5) +#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12))
static int mmap_is_legacy(struct rlimit *rlim_stack) { @@ -35,6 +36,15 @@ static int mmap_is_legacy(struct rlimit *rlim_stack) static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack) { unsigned long gap = rlim_stack->rlim_cur; + unsigned long pad = stack_guard_gap; + + /* Account for stack randomization if necessary */ + if (current->flags & PF_RANDOMIZE) + pad += (STACK_RND_MASK << PAGE_SHIFT); + + /* Values close to RLIM_INFINITY can overflow. */ + if (gap + pad > gap) + gap += pad;
if (gap < MIN_GAP) gap = MIN_GAP;
From: Alexandre Ghiti alex@ghiti.fr
[ Upstream commit 86e568e9c0525fc40e76d827212d5e9721cf7504 ]
mmap base address must be computed wrt stack top address, using TASK_SIZE is wrong since STACK_TOP and TASK_SIZE are not equivalent.
Link: http://lkml.kernel.org/r/20190730055113.23635-8-alex@ghiti.fr Signed-off-by: Alexandre Ghiti alex@ghiti.fr Acked-by: Kees Cook keescook@chromium.org Reviewed-by: Luis Chamberlain mcgrof@kernel.org Cc: Albert Ou aou@eecs.berkeley.edu Cc: Alexander Viro viro@zeniv.linux.org.uk Cc: Catalin Marinas catalin.marinas@arm.com Cc: Christoph Hellwig hch@infradead.org Cc: Christoph Hellwig hch@lst.de Cc: James Hogan jhogan@kernel.org Cc: Palmer Dabbelt palmer@sifive.com Cc: Paul Burton paul.burton@mips.com Cc: Ralf Baechle ralf@linux-mips.org Cc: Russell King linux@armlinux.org.uk Cc: Will Deacon will.deacon@arm.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mm/mmap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c index bff3d00bda5be..0b94b674aa91f 100644 --- a/arch/arm/mm/mmap.c +++ b/arch/arm/mm/mmap.c @@ -19,7 +19,7 @@
/* gap between mmap and stack */ #define MIN_GAP (128*1024*1024UL) -#define MAX_GAP ((TASK_SIZE)/6*5) +#define MAX_GAP ((STACK_TOP)/6*5) #define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12))
static int mmap_is_legacy(struct rlimit *rlim_stack) @@ -51,7 +51,7 @@ static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack) else if (gap > MAX_GAP) gap = MAX_GAP;
- return PAGE_ALIGN(TASK_SIZE - gap - rnd); + return PAGE_ALIGN(STACK_TOP - gap - rnd); }
/*
linux-stable-mirror@lists.linaro.org