ARM: OMAP2+: prm44xx: Fix section annotation on omap44xx_prm_enable_io_wakeup
Subsystems (21)
Sasha Levin
maintainerPATCH 1/69 ARM: OMAP2+: prm44xx: Fix section annotation on omap44xx_prm_enable_io_wakeup
From: Nathan Chancellor <[email protected]>
[ Upstream commit eef3dc34a1e0b01d53328b88c25237bcc7323777 ]
When building the kernel with Clang, the following section mismatch warning appears:
WARNING: vmlinux.o(.text+0x38b3c): Section mismatch in reference from the function omap44xx_prm_late_init() to the function .init.text:omap44xx_prm_enable_io_wakeup()
The function omap44xx_prm_late_init() references
the function __init omap44xx_prm_enable_io_wakeup().
This is often because omap44xx_prm_late_init lacks a __init annotation or the annotation of omap44xx_prm_enable_io_wakeup is wrong.
Remove the __init annotation from omap44xx_prm_enable_io_wakeup so there is no more mismatch.
--- arch/arm/mach-omap2/prm44xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mach-omap2/prm44xx.c +1 -1
@@ -344,7 +344,7 @@ static void omap44xx_prm_reconfigure_io_chain(void)* to occur, WAKEUPENABLE bits must be set in the pad mux registers, and * omap44xx_prm_reconfigure_io_chain() must be called. No return value. */ -static void __init omap44xx_prm_enable_io_wakeup (void ) +static void omap44xx_prm_enable_io_wakeup (void ) {s32 inst =omap4_prmst_get_prm_dev_inst ();
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 2/69 ASoC: rsnd: fixup clock start checker
From: Kuninori Morimoto <[email protected]>
[ Upstream commit 3ee9a76a8c5a10e1bfb04b81db767c6d562ddaf3 ]
commit 4d230d12710646 ("ASoC: rsnd: fixup not to call clk_get/set under non-atomic") fixuped clock start timing. But it exchanged clock start checker from ssi->usrcnt to ssi->rate.
Current rsnd_ssi_master_clk_start() is called from .prepare, but some player (for example GStreamer) might calls it many times. In such case, the checker might returns error even though it was not error. It should check ssi->usrcnt instead of ssi->rate. This patch fixup it. Without this patch, GStreamer can't switch 48kHz / 44.1kHz.
--- sound/soc/sh/rcar/ssi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/sh/rcar/ssi.c +1 -1
@@ -280,7 +280,7 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod,if (rsnd_ssi_is_multi_slave (mod, io))return 0 ; -if (ssi->rate) { +if (ssi->usrcnt >1 ) {if (ssi->rate != rate) {dev_err (dev,"SSI parent/child should use same rate\n" );return -EINVAL ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 3/69 iio:st_magn: Fix enable device after trigger
In reply to Sasha LevinFrom: Martin Kelly <[email protected]>
[ Upstream commit fe5192ac81ad0d4dfe1395d11f393f0513c15f7f ]
Currently, we enable the device before we enable the device trigger. At high frequencies, this can cause interrupts that don't yet have a poll function associated with them and are thus treated as spurious. At high frequencies with level interrupts, this can even cause an interrupt storm of repeated spurious interrupts (~100,000 on my Beagleboard with the LSM9DS1 magnetometer). If these repeat too much, the interrupt will get disabled and the device will stop functioning.
To prevent these problems, enable the device prior to enabling the device trigger, and disable the divec prior to disabling the trigger. This means there's no window of time during which the device creates interrupts but we have no trigger to answer them.
--- drivers/iio/magnetometer/st_magn_buffer.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-)
drivers/iio/magnetometer/st_magn_buffer.c +3 -9
@@ -30,11 +30,6 @@ int st_magn_trig_set_state(struct iio_trigger *trig, bool state)return st_sensors_set_dataready_irq (indio_dev, state); } -static int st_magn_buffer_preenable (struct iio_dev *indio_dev) -{ -return st_sensors_set_enable (indio_dev, true); -} -static int st_magn_buffer_postenable (struct iio_dev *indio_dev) {int err;
@@ -50,7 +45,7 @@ static int st_magn_buffer_postenable(struct iio_dev *indio_dev)if (err <0 ) goto st_magn_buffer_postenable_error; -return err; +return st_sensors_set_enable (indio_dev, true); st_magn_buffer_postenable_error:kfree (mdata->buffer_data);
@@ -63,11 +58,11 @@ static int st_magn_buffer_predisable(struct iio_dev *indio_dev)int err;struct st_sensor_data *mdata =iio_priv (indio_dev); - err =iio_triggered_buffer_predisable (indio_dev); + err =st_sensors_set_enable (indio_dev, false);if (err <0 ) goto st_magn_buffer_predisable_error; - err =st_sensors_set_enable (indio_dev, false); + err =iio_triggered_buffer_predisable (indio_dev); st_magn_buffer_predisable_error:kfree (mdata->buffer_data);
@@ -75,7 +70,6 @@ static int st_magn_buffer_predisable(struct iio_dev *indio_dev) }static const struct iio_buffer_setup_ops st_magn_buffer_setup_ops = { - .preenable = &st_magn_buffer_preenable, .postenable = &st_magn_buffer_postenable, .predisable = &st_magn_buffer_predisable, };
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 4/69 staging: rtl8723bs: Fix the return value in case of error in 'rtw_wx_read32()'
In reply to Sasha LevinFrom: Christophe JAILLET <[email protected]>
[ Upstream commit c3e43d8b958bd6849817393483e805d8638a8ab7 ]
We return 0 unconditionally in 'rtw_wx_read32()'.
However, 'ret' is set to some error codes in several error handling paths.
Return 'ret' instead to propagate the error code.
--- drivers/staging/rtl8723bs/os_dep/ioctl_linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/rtl8723bs/os_dep/ioctl_linux.c +1 -1
@@ -2383,7 +2383,7 @@ static int rtw_wx_read32(struct net_device *dev, exit:kfree (ptmp); -return 0 ; +return ret; } static int rtw_wx_write32(struct net_device *dev,
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 5/69 ARM: dts: logicpd-somlv: Fix interrupt on mmc3_dat1
In reply to Sasha LevinFrom: Adam Ford <[email protected]>
[ Upstream commit 3d8b804bc528d3720ec0c39c212af92dafaf6e84 ]
The interrupt on mmc3_dat1 is wrong which prevents this from appearing in /proc/interrupts.
DM3730 SOM-LV") #Kernel 4.9+
--- arch/arm/boot/dts/logicpd-som-lv.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/logicpd-som-lv.dtsi +1 -1
@@ -123,7 +123,7 @@ }; &mmc3 { - interrupts-extended = <&intc 94 &omap3_pmx_core2 0x46>; + interrupts-extended = <&intc 94 &omap3_pmx_core 0x136>; pinctrl-0 = <&mmc3_pins &wl127x_gpio>; pinctrl-names = "default"; vmmc-supply = <&wl12xx_vmmc>;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 6/69 ARM: OMAP1: ams-delta: Fix possible use of uninitialized field
In reply to Sasha LevinFrom: Janusz Krzysztofik <[email protected]>
[ Upstream commit cec83ff1241ec98113a19385ea9e9cfa9aa4125b ]
While playing with initialization order of modem device, it has been discovered that under some circumstances (early console init, I believe) its .pm() callback may be called before the uart_port->private_data pointer is initialized from plat_serial8250_port->private_data, resulting in NULL pointer dereference. Fix it by checking for uninitialized pointer before using it in modem_pm().
--- arch/arm/mach-omap1/board-ams-delta.c | 3 +++ 1 file changed, 3 insertions(+)
arch/arm/mach-omap1/board-ams-delta.c +3 -0
@@ -512,6 +512,9 @@ static void modem_pm(struct uart_port *port, unsigned int state, unsigned old)struct modem_private_data *priv = port->private_data;int ret; +if (!priv) +return ; +if (IS_ERR (priv->regulator))return ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 7/69 sysv: return 'err' instead of 0 in __sysv_write_inode
In reply to Sasha LevinFrom: YueHaibing <[email protected]>
[ Upstream commit c4b7d1ba7d263b74bb72e9325262a67139605cde ]
Fixes gcc '-Wunused-but-set-variable' warning:
fs/sysv/inode.c: In function '__sysv_write_inode':fs/sysv/inode.c:239:6: warning:
variable 'err' set but not used [-Wunused-but-set-variable]
__sysv_write_inode should return 'err' instead of 0
--- fs/sysv/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/sysv/inode.c +1 -1
@@ -275,7 +275,7 @@ static int __sysv_write_inode(struct inode *inode, int wait) } }brelse (bh); -return 0 ; +return err; }int sysv_write_inode (struct inode *inode,struct writeback_control *wbc)
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 8/69 selftests: add script to stress-test nft packet path vs. control plane
In reply to Sasha LevinFrom: Florian Westphal <[email protected]>
[ Upstream commit 25d8bcedbf4329895dbaf9dd67baa6f18dad918c ]
Start flood ping for each cpu while loading/flushing rulesets to make sure we do not access already-free'd rules from nf_tables evaluation loop.
Also add this to TARGETS so 'make run_tests' in selftest dir runs it automatically.
This would have caught the bug fixed in previous change ("netfilter: nf_tables: do not skip inactive chains during generation update") sooner.
--- tools/testing/selftests/Makefile | 1 + tools/testing/selftests/netfilter/Makefile | 6 ++ tools/testing/selftests/netfilter/config | 2 + .../selftests/netfilter/nft_trans_stress.sh | 78 +++++++++++++++++++ 4 files changed, 87 insertions(+) create mode 100644 tools/testing/selftests/netfilter/Makefile create mode 100644 tools/testing/selftests/netfilter/config create mode 100755 tools/testing/selftests/netfilter/nft_trans_stress.sh
tools/testing/selftests/Makefile +1 -0
@@ -20,6 +20,7 @@ TARGETS += memory-hotplug TARGETS += mount TARGETS += mqueue TARGETS += net +TARGETS += netfilter TARGETS += nsfs TARGETS += powerpc TARGETS += pstore
tools/testing/selftests/netfilter/Makefile new file +6 -0
@@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0 +# Makefile for netfilter selftests + +TEST_PROGS := nft_trans_stress.sh + +include ../lib.mk
tools/testing/selftests/netfilter/config new file +2 -0
@@ -0,0 +1,2 @@ +CONFIG_NET_NS=y +NF_TABLES_INET=y
tools/testing/selftests/netfilter/nft_trans_stress.sh new file +78 -0
78 lines not on this page · raw message
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 9/69 netfilter: nf_tables: fix use-after-free when deleting compat expressions
In reply to Sasha LevinFrom: Florian Westphal <[email protected]>
[ Upstream commit 29e3880109e357fdc607b4393f8308cef6af9413 ]
nft_compat ops do not have static storage duration, unlike all other expressions.
When nf_tables_expr_destroy() returns, expr->ops might have been free'd already, so we need to store next address before calling expression destructor.
For same reason, we can't deref match pointer after nft_xt_put().
This can be easily reproduced by adding msleep() before nft_match_destroy() returns.
--- net/netfilter/nf_tables_api.c | 5 +++-- net/netfilter/nft_compat.c | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-)
net/netfilter/nf_tables_api.c +3 -2
@@ -2252,7 +2252,7 @@ static int nf_tables_getrule(struct net *net, struct sock *nlsk,static void nf_tables_rule_destroy (const struct nft_ctx *ctx,struct nft_rule *rule) { -struct nft_expr *expr; +struct nft_expr *expr, *next;/* * Careful: some expressions might not be initialized in case this
@@ -2260,8 +2260,9 @@ static void nf_tables_rule_destroy(const struct nft_ctx *ctx,*/ expr =nft_expr_first (rule);while (expr !=nft_expr_last (rule) && expr->ops) { + next =nft_expr_next (expr);nf_tables_expr_destroy (ctx, expr); - expr =nft_expr_next (expr); + expr = next; }kfree (rule); }
net/netfilter/nft_compat.c +2 -1
@@ -497,6 +497,7 @@ __nft_match_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr, void *info) {struct xt_match *match = expr->ops->data; +struct module *me = match->me;struct xt_mtdtor_param par; par.net = ctx->net;
@@ -507,7 +508,7 @@ __nft_match_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr, par.match->destroy (&par); if (nft_xt_put(container_of(expr->ops, struct nft_xt, ops))) -module_put (match->me); +module_put (me); } static void
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 10/69 hwmon (ina2xx) Fix NULL id pointer in probe()
In reply to Sasha LevinFrom: Nicolin Chen <[email protected]>
[ Upstream commit 70df9ebbd82c794ddfbb49d45b337f18d5588dc2 ]
When using DT configurations, the id pointer might turn out to be NULL. Then the driver encounters NULL pointer access:
Unable to handle kernel read from unreadable memory at vaddr 00000018 [...] PC is at ina2xx_probe+0x114/0x200 LR is at ina2xx_probe+0x10c/0x200 [...] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
The reason is that i2c core returns the id pointer by matching id_table with client->name, while the client->name is actually using the name from the first string in the DT compatible list, not the best one. So i2c core would fail to match the id_table if the best matched compatible string isn't the first one, and then would return a NULL id pointer.
This probably should be fixed in i2c core. But it doesn't hurt to make the driver robust. So this patch fixes it by using the "chip" that's added to unify both DT and non-DT configurations.
Additionally, since id pointer could be null, so as id->name:
ina2xx 10-0047: power monitor (null) (Rshunt = 1000 uOhm) ina2xx 10-0048: power monitor (null) (Rshunt = 10000 uOhm)
So this patch also fixes NULL name pointer, using client->name to play safe and to align with hwmon->name.
--- drivers/hwmon/ina2xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/hwmon/ina2xx.c +2 -2
@@ -491,7 +491,7 @@ static int ina2xx_probe(struct i2c_client *client, } data->groups[group++] = &ina2xx_group; -if (id->driver_data == ina226) +if (chip == ina226) data->groups[group++] = &ina226_group; hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
@@ -500,7 +500,7 @@ static int ina2xx_probe(struct i2c_client *client,return PTR_ERR (hwmon_dev);dev_info (dev,"power monitor %s (Rshunt = %li uOhm)\n" , - id->name, data->rshunt); + client->name, data->rshunt);return 0 ; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 11/69 ASoC: wm_adsp: Fix dma-unsafe read of scratch registers
In reply to Sasha LevinFrom: Richard Fitzgerald <[email protected]>
[ Upstream commit 20e00db2f59bdddf8a8e241473ef8be94631d3ae ]
Stack memory isn't DMA-safe so it isn't safe to use either regmap_raw_read or regmap_bulk_read to read into stack memory.
The two functions to read the scratch registers were using stack memory and regmap_raw_read. It's not worth allocating memory just for this trivial read, and it isn't time-critical. A simple regmap_read for each register is sufficient.
--- sound/soc/codecs/wm_adsp.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-)
sound/soc/codecs/wm_adsp.c +20 -17
@@ -787,38 +787,41 @@ static unsigned int wm_adsp_region_to_reg(struct wm_adsp_region const *mem,static void wm_adsp2_show_fw_status (struct wm_adsp *dsp) { -u16 scratch[4 ]; +unsigned int scratch[4 ]; +unsigned int addr = dsp->base +ADSP2_SCRATCH0 ; +unsigned int i;int ret; - ret =regmap_raw_read (dsp->regmap, dsp->base +ADSP2_SCRATCH0 , - scratch,sizeof (scratch)); -if (ret) { -adsp_err (dsp,"Failed to read SCRATCH regs: %d\n" , ret); -return ; +for (i =0 ; i <ARRAY_SIZE (scratch); ++i) { + ret =regmap_read (dsp->regmap, addr + i, &scratch[i]); +if (ret) { +adsp_err (dsp,"Failed to read SCRATCH%u: %d\n" , i, ret); +return ; + } }adsp_dbg (dsp,"FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n" , -be16_to_cpu (scratch[0 ]), -be16_to_cpu (scratch[1 ]), -be16_to_cpu (scratch[2 ]), -be16_to_cpu (scratch[3 ])); + scratch[0 ], scratch[1 ], scratch[2 ], scratch[3 ]); }static void wm_adsp2v2_show_fw_status (struct wm_adsp *dsp) { -u32 scratch[2 ]; +unsigned int scratch[2 ];int ret; - ret =regmap_raw_read (dsp->regmap, dsp->base +ADSP2V2_SCRATCH0_1 , - scratch,sizeof (scratch)); - + ret =regmap_read (dsp->regmap, dsp->base +ADSP2V2_SCRATCH0_1 , + &scratch[0 ]);if (ret) { -adsp_err (dsp,"Failed to read SCRATCH regs: %d\n" , ret); +adsp_err (dsp,"Failed to read SCRATCH0_1: %d\n" , ret);return ; } - scratch[0 ] =be32_to_cpu (scratch[0 ]); - scratch[1 ] =be32_to_cpu (scratch[1 ]); + ret =regmap_read (dsp->regmap, dsp->base +ADSP2V2_SCRATCH2_3 , + &scratch[1 ]); +if (ret) { +adsp_err (dsp,"Failed to read SCRATCH2_3: %d\n" , ret); +return ; + } adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", scratch[0] & 0xFFFF,
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 12/69 s390/cpum_cf: Reject request for sampling in event initialization
In reply to Sasha LevinFrom: Thomas Richter <[email protected]>
[ Upstream commit 613a41b0d16e617f46776a93b975a1eeea96417c ]
On s390 command perf top fails
[root@s35lp76 perf] # ./perf top -F100000 --stdio
Error:
cycles: PMU Hardware doesn't support sampling/overflow-interrupts.
Try 'perf stat'
[root@s35lp76 perf] #
Using event -e rb0000 works as designed. Event rb0000 is the event number of the sampling facility for basic sampling.
During system start up the following PMUs are installed in the kernel's PMU list (from head to tail):
cpum_cf --> s390 PMU counter facility device driver cpum_sf --> s390 PMU sampling facility device driver uprobe
kprobe
tracepoint
task_clock
cpu_clock
Perf top executes following functions and calls perf_event_open(2) system call with different parameters many times:
cmd_top
--> __cmd_top
--> perf_evlist__add_default
--> __perf_evlist__add_default
--> perf_evlist__new_cycles (creates event type:0 (HW)
config 0 (CPU_CYCLES)
--> perf_event_attr__set_max_precise_ip
Uses perf_event_open(2) to detect correct
precise_ip level. Fails 3 times on s390 which is ok.Then functions cmd_top
--> __cmd_top
--> perf_top__start_counters
-->perf_evlist__config
--> perf_can_comm_exec
--> perf_probe_api
This functions test support for the following events:
"cycles:u", "instructions:u", "cpu-clock:u" using --> perf_do_probe_api
--> perf_event_open_cloexec
Test the close on exec flag support with perf_event_open(2).
perf_do_probe_api returns true if the event is supported.
The function returns true because event cpu-clock is supported by the PMU cpu_clock.
This is achieved by many calls to perf_event_open(2).
Function perf_top__start_counters now calls perf_evsel__open() for every event, which is the default event cpu_cycles (config:0) and type HARDWARE (type:0) which a predfined frequence of 4000.
Given the above order of the PMU list, the PMU cpum_cf gets called first and returns 0, which indicates support for this sampling. The event is fully allocated in the function perf_event_open (file kernel/event/core.c near line 10521 and the following check fails:
event = perf_event_alloc(&attr, cpu, task, group_leader, NULL,
NULL, NULL, cgroup_fd);
if (IS_ERR(event)) {
err = PTR_ERR(event);
goto err_cred;
}
if (is_sampling_event(event)) {
if (event->pmu->capabilities & PERF_PMU_CAP_NO_INTERRUPT) {
err = -EOPNOTSUPP;
goto err_alloc;
}
}The check for the interrupt capabilities fails and the system call perf_event_open() returns -EOPNOTSUPP (-95).
Add a check to return -ENODEV when sampling is requested in PMU cpum_cf. This allows common kernel code in the perf_event_open() system call to test the next PMU in above list.
--- arch/s390/kernel/perf_cpum_cf.c | 2 ++ 1 file changed, 2 insertions(+)
arch/s390/kernel/perf_cpum_cf.c +2 -0
@@ -349,6 +349,8 @@ static int __hw_perf_event_init(struct perf_event *event)break ;case PERF_TYPE_HARDWARE : +if (is_sampling_event (event))/* No sampling support */ +return -ENOENT ; ev = attr->config;/* Count user space (problem-state) only */ if (!attr->exclude_user && attr->exclude_kernel) {
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 13/69 hwmon: (ina2xx) Fix current value calculation
In reply to Sasha LevinFrom: Nicolin Chen <[email protected]>
[ Upstream commit 38cd989ee38c16388cde89db5b734f9d55b905f9 ]
The current register (04h) has a sign bit at MSB. The comments for this calculation also mention that it's a signed register.
However, the regval is unsigned type so result of calculation turns out to be an incorrect value when current is negative.
This patch simply fixes this by adding a casting to s16.
--- drivers/hwmon/ina2xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwmon/ina2xx.c +1 -1
@@ -274,7 +274,7 @@ static int ina2xx_get_value(struct ina2xx_data *data, u8 reg,break ;case INA2XX_CURRENT :/* signed register, result in mA */ - val = regval * data->current_lsb_uA; + val = (s16 )regval * data->current_lsb_uA; val =DIV_ROUND_CLOSEST (val,1000 );break ;case INA2XX_CALIBRATION :
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 14/69 ASoC: omap-abe-twl6040: Fix missing audio card caused by deferred probing
In reply to Sasha LevinFrom: Peter Ujfalusi <[email protected]>
[ Upstream commit 76836fd354922ebe4798a64fda01f8dc6a8b0984 ]
The machine driver fails to probe in next-20181113 with:
[ 2.539093] omap-abe-twl6040 sound: ASoC: CODEC DAI twl6040-legacy not registered [ 2.546630] omap-abe-twl6040 sound: devm_snd_soc_register_card() failed: -517 ... [ 3.693206] omap-abe-twl6040 sound: ASoC: Both platform name/of_node are set for TWL6040 [ 3.701446] omap-abe-twl6040 sound: ASoC: failed to init link TWL6040 [ 3.708007] omap-abe-twl6040 sound: devm_snd_soc_register_card() failed: -22 [ 3.715148] omap-abe-twl6040: probe of sound failed with error -22
Bisect pointed to a merge commit:
first bad commit: [0f688ab20a540aafa984c5dbd68a71debebf4d7f] Merge remote-tracking branch 'net-next/master'
and a diff between a working kernel does not reveal anything which would explain the change in behavior.
Further investigation showed that on the second try of loading fails because the dai_link->platform is no longer NULL and it might be pointing to uninitialized memory.
The fix is to move the snd_soc_dai_link and snd_soc_card inside of the abe_twl6040 struct, which is dynamically allocated every time the driver probes.
--- sound/soc/omap/omap-abe-twl6040.c | 67 +++++++++++++------------------ 1 file changed, 29 insertions(+), 38 deletions(-)
sound/soc/omap/omap-abe-twl6040.c +29 -38
@@ -36,6 +36,8 @@#include "../codecs/twl6040.h" struct abe_twl6040 { +struct snd_soc_card card; +struct snd_soc_dai_link dai_links[2 ];int jack_detection;/* board can detect jack events */ int mclk_freq;/* MCLK frequency speed for twl6040 */ };
@@ -208,40 +210,10 @@ static int omap_abe_dmic_init(struct snd_soc_pcm_runtime *rtd) ARRAY_SIZE(dmic_audio_map)); } -/* Digital audio interface glue - connects codec <--> CPU */ -static struct snd_soc_dai_link abe_twl6040_dai_links[] = { - { - .name ="TWL6040" , - .stream_name ="TWL6040" , - .codec_dai_name ="twl6040-legacy" , - .codec_name ="twl6040-codec" , - .init = omap_abe_twl6040_init, - .ops = &omap_abe_ops, - }, - { - .name ="DMIC" , - .stream_name ="DMIC Capture" , - .codec_dai_name ="dmic-hifi" , - .codec_name ="dmic-codec" , - .init = omap_abe_dmic_init, - .ops = &omap_abe_dmic_ops, - }, -}; - -/* Audio machine driver */ -static struct snd_soc_card omap_abe_card = { - .owner =THIS_MODULE , - - .dapm_widgets = twl6040_dapm_widgets, - .num_dapm_widgets =ARRAY_SIZE (twl6040_dapm_widgets), - .dapm_routes = audio_map, - .num_dapm_routes =ARRAY_SIZE (audio_map), -}; -static int omap_abe_probe (struct platform_device *pdev) {struct device_node *node = pdev->dev.of_node; -struct snd_soc_card *card = &omap_abe_card; +struct snd_soc_card *card;struct device_node *dai_node;struct abe_twl6040 *priv;int num_links =0 ;
@@ -252,12 +224,18 @@ static int omap_abe_probe(struct platform_device *pdev)return -ENODEV ; } - card->dev = &pdev->dev; - priv =devm_kzalloc (&pdev->dev,sizeof (struct abe_twl6040 ),GFP_KERNEL );if (priv ==NULL )return -ENOMEM ; + card = &priv->card; + card->dev = &pdev->dev; + card->owner =THIS_MODULE ; + card->dapm_widgets = twl6040_dapm_widgets; + card->num_dapm_widgets =ARRAY_SIZE (twl6040_dapm_widgets); + card->dapm_routes = audio_map; + card->num_dapm_routes =ARRAY_SIZE (audio_map); +if (snd_soc_of_parse_card_name (card,"ti,model" )) {dev_err (&pdev->dev,"Card name is not provided\n" );return -ENODEV ;
@@ -274,14 +252,27 @@ static int omap_abe_probe(struct platform_device *pdev)dev_err (&pdev->dev,"McPDM node is not provided\n" );return -EINVAL ; } - abe_twl6040_dai_links[0 ].cpu_of_node = dai_node; - abe_twl6040_dai_links[0 ].platform_of_node = dai_node; + + priv->dai_links[0 ].name ="DMIC" ; + priv->dai_links[0 ].stream_name ="TWL6040" ; + priv->dai_links[0 ].cpu_of_node = dai_node; + priv->dai_links[0 ].platform_of_node = dai_node; + priv->dai_links[0 ].codec_dai_name ="twl6040-legacy" ; + priv->dai_links[0 ].codec_name ="twl6040-codec" ; + priv->dai_links[0 ].init = omap_abe_twl6040_init; + priv->dai_links[0 ].ops = &omap_abe_ops; dai_node =of_parse_phandle (node,"ti,dmic" ,0 );if (dai_node) { num_links =2 ; - abe_twl6040_dai_links[1 ].cpu_of_node = dai_node; - abe_twl6040_dai_links[1 ].platform_of_node = dai_node; + priv->dai_links[1 ].name ="TWL6040" ; + priv->dai_links[1 ].stream_name ="DMIC Capture" ; + priv->dai_links[1 ].cpu_of_node = dai_node; + priv->dai_links[1 ].platform_of_node = dai_node; + priv->dai_links[1 ].codec_dai_name ="dmic-hifi" ; + priv->dai_links[1 ].codec_name ="dmic-codec" ; + priv->dai_links[1 ].init = omap_abe_dmic_init; + priv->dai_links[1 ].ops = &omap_abe_dmic_ops; }else { num_links =1 ; }
@@ -300,7 +291,7 @@ static int omap_abe_probe(struct platform_device *pdev)return -ENODEV ; } - card->dai_link = abe_twl6040_dai_links; + card->dai_link = priv->dai_links; card->num_links = num_links;snd_soc_card_set_drvdata (card, priv);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 15/69 ASoC: dapm: Recalculate audio map forcely when card instantiated
In reply to Sasha LevinFrom: Tzung-Bi Shih <[email protected]>
[ Upstream commit 882eab6c28d23a970ae73b7eb831b169a672d456 ]
Audio map are possible in wrong state before card->instantiated has been set to true. Imaging the following examples:
time 1: at the beginning
in:-1 in:-1 in:-1 in:-1
out:-1 out:-1 out:-1 out:-1
SIGGEN A B Spk
time 2: after someone called snd_soc_dapm_new_widgets() (e.g. create_fill_widget_route_map() in sound/soc/codecs/hdac_hdmi.c)
in:1 in:0 in:0 in:0
out:0 out:0 out:0 out:1
SIGGEN A B Spk
time 3: routes added
in:1 in:0 in:0 in:0
out:0 out:0 out:0 out:1
SIGGEN -----> A -----> B ---> Spk
In the end, the path should be powered on but it did not. At time 3, "in" of SIGGEN and "out" of Spk did not propagate to their neighbors because snd_soc_dapm_add_path() will not invalidate the paths if the card has not instantiated (i.e. card->instantiated is false). To correct the state of audio map, recalculate the whole map forcely.
--- sound/soc/soc-core.c | 1 + 1 file changed, 1 insertion(+)
sound/soc/soc-core.c +1 -0
@@ -2307,6 +2307,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) } card->instantiated =1 ; +dapm_mark_endpoints_dirty (card);snd_soc_dapm_sync (&card->dapm);mutex_unlock (&card->mutex);mutex_unlock (&client_mutex);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 16/69 iio/hid-sensors: Fix IIO_CHAN_INFO_RAW returning wrong values for signed numbers
In reply to Sasha LevinFrom: Hans de Goede <[email protected]>
[ Upstream commit 0145b50566e7de5637e80ecba96c7f0e6fff1aad ]
Before this commit sensor_hub_input_attr_get_raw_value() failed to take the signedness of 16 and 8 bit values into account, returning e.g. 65436 instead of -100 for the z-axis reading of an accelerometer.
This commit adds a new is_signed parameter to the function and makes all callers pass the appropriate value for this.
While at it, this commit also fixes up some neighboring lines where statements were needlessly split over 2 lines to improve readability.
--- drivers/hid/hid-sensor-custom.c | 2 +- drivers/hid/hid-sensor-hub.c | 13 ++++++++++--- drivers/iio/accel/hid-sensor-accel-3d.c | 5 ++++- drivers/iio/gyro/hid-sensor-gyro-3d.c | 5 ++++- drivers/iio/humidity/hid-sensor-humidity.c | 3 ++- drivers/iio/light/hid-sensor-als.c | 8 +++++--- drivers/iio/light/hid-sensor-prox.c | 8 +++++--- drivers/iio/magnetometer/hid-sensor-magn-3d.c | 8 +++++--- drivers/iio/orientation/hid-sensor-incl-3d.c | 8 +++++--- drivers/iio/pressure/hid-sensor-press.c | 8 +++++--- drivers/iio/temperature/hid-sensor-temperature.c | 3 ++- drivers/rtc/rtc-hid-sensor-time.c | 2 +- include/linux/hid-sensor-hub.h | 4 +++- 13 files changed, 52 insertions(+), 25 deletions(-)
drivers/hid/hid-sensor-custom.c +1 -1
@@ -358,7 +358,7 @@ static ssize_t show_value(struct device *dev, struct device_attribute *attr, sensor_inst->hsdev, sensor_inst->hsdev->usage, usage, report_id, - SENSOR_HUB_SYNC); + SENSOR_HUB_SYNC, false); }else if (!strncmp (name,"units" ,strlen ("units" ))) value = sensor_inst->fields[field_index].attribute.units;else if (!strncmp (name,"unit-expo" ,strlen ("unit-expo" )))
drivers/hid/hid-sensor-hub.c +10 -3
@@ -299,7 +299,8 @@ EXPORT_SYMBOL_GPL(sensor_hub_get_feature);int sensor_hub_input_attr_get_raw_value (struct hid_sensor_hub_device *hsdev,u32 usage_id,u32 attr_usage_id,u32 report_id, -enum sensor_hub_read_flags flag) +enum sensor_hub_read_flags flag, +bool is_signed) {struct sensor_hub_data *data =hid_get_drvdata (hsdev->hdev);unsigned long flags;
@@ -331,10 +332,16 @@ int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev, &hsdev->pending.ready, HZ*5);switch (hsdev->pending.raw_size) {case 1 : - ret_val = *(u8 *)hsdev->pending.raw_data; +if (is_signed) + ret_val = *(s8 *)hsdev->pending.raw_data; +else + ret_val = *(u8 *)hsdev->pending.raw_data;break ;case 2 : - ret_val = *(u16 *)hsdev->pending.raw_data; +if (is_signed) + ret_val = *(s16 *)hsdev->pending.raw_data; +else + ret_val = *(u16 *)hsdev->pending.raw_data;break ;case 4 : ret_val = *(u32 *)hsdev->pending.raw_data;
drivers/iio/accel/hid-sensor-accel-3d.c +4 -1
@@ -149,6 +149,7 @@ static int accel_3d_read_raw(struct iio_dev *indio_dev,int report_id =-1 ;u32 address;int ret_type; +s32 min;struct hid_sensor_hub_device *hsdev = accel_state->common_attributes.hsdev;
@@ -158,12 +159,14 @@ static int accel_3d_read_raw(struct iio_dev *indio_dev,case 0 :hid_sensor_power_state (&accel_state->common_attributes, true); report_id = accel_state->accel[chan->scan_index].report_id; + min = accel_state->accel[chan->scan_index].logical_minimum; address = accel_3d_addresses[chan->scan_index];if (report_id >=0 ) *val =sensor_hub_input_attr_get_raw_value ( accel_state->common_attributes.hsdev, hsdev->usage, address, report_id, -SENSOR_HUB_SYNC ); +SENSOR_HUB_SYNC , + min <0 );else { *val =0 ; hid_sensor_power_state(&accel_state->common_attributes,
drivers/iio/gyro/hid-sensor-gyro-3d.c +4 -1
@@ -111,6 +111,7 @@ static int gyro_3d_read_raw(struct iio_dev *indio_dev,int report_id =-1 ;u32 address;int ret_type; +s32 min; *val =0 ; *val2 =0 ;
@@ -118,13 +119,15 @@ static int gyro_3d_read_raw(struct iio_dev *indio_dev,case 0 :hid_sensor_power_state (&gyro_state->common_attributes, true); report_id = gyro_state->gyro[chan->scan_index].report_id; + min = gyro_state->gyro[chan->scan_index].logical_minimum; address = gyro_3d_addresses[chan->scan_index];if (report_id >=0 ) *val =sensor_hub_input_attr_get_raw_value ( gyro_state->common_attributes.hsdev,HID_USAGE_SENSOR_GYRO_3D , address, report_id, -SENSOR_HUB_SYNC ); +SENSOR_HUB_SYNC , + min <0 );else { *val =0 ; hid_sensor_power_state(&gyro_state->common_attributes,
drivers/iio/humidity/hid-sensor-humidity.c +2 -1
@@ -75,7 +75,8 @@ static int humidity_read_raw(struct iio_dev *indio_dev,HID_USAGE_SENSOR_HUMIDITY ,HID_USAGE_SENSOR_ATMOSPHERIC_HUMIDITY , humid_st->humidity_attr.report_id, - SENSOR_HUB_SYNC); +SENSOR_HUB_SYNC , + humid_st->humidity_attr.logical_minimum < 0);hid_sensor_power_state (&humid_st->common_attributes, false);return IIO_VAL_INT ;
drivers/iio/light/hid-sensor-als.c +5 -3
@@ -93,6 +93,7 @@ static int als_read_raw(struct iio_dev *indio_dev,int report_id =-1 ;u32 address;int ret_type; +s32 min; *val =0 ; *val2 =0 ;
@@ -102,8 +103,8 @@ static int als_read_raw(struct iio_dev *indio_dev,case CHANNEL_SCAN_INDEX_INTENSITY :case CHANNEL_SCAN_INDEX_ILLUM : report_id = als_state->als_illum.report_id; - address = -HID_USAGE_SENSOR_LIGHT_ILLUM ; + min = als_state->als_illum.logical_minimum; + address =HID_USAGE_SENSOR_LIGHT_ILLUM ;break ;default : report_id =-1 ;
@@ -116,7 +117,8 @@ static int als_read_raw(struct iio_dev *indio_dev, als_state->common_attributes.hsdev,HID_USAGE_SENSOR_ALS , address, report_id, - SENSOR_HUB_SYNC); +SENSOR_HUB_SYNC , + min < 0);hid_sensor_power_state (&als_state->common_attributes, false); }else {
drivers/iio/light/hid-sensor-prox.c +5 -3
@@ -73,6 +73,7 @@ static int prox_read_raw(struct iio_dev *indio_dev,int report_id =-1 ;u32 address;int ret_type; +s32 min; *val =0 ; *val2 =0 ;
@@ -81,8 +82,8 @@ static int prox_read_raw(struct iio_dev *indio_dev,switch (chan->scan_index) {case CHANNEL_SCAN_INDEX_PRESENCE : report_id = prox_state->prox_attr.report_id; - address = -HID_USAGE_SENSOR_HUMAN_PRESENCE ; + min = prox_state->prox_attr.logical_minimum; + address =HID_USAGE_SENSOR_HUMAN_PRESENCE ;break ;default : report_id =-1 ;
@@ -95,7 +96,8 @@ static int prox_read_raw(struct iio_dev *indio_dev, prox_state->common_attributes.hsdev,HID_USAGE_SENSOR_PROX , address, report_id, - SENSOR_HUB_SYNC); +SENSOR_HUB_SYNC , + min < 0);hid_sensor_power_state (&prox_state->common_attributes, false); }else {
drivers/iio/magnetometer/hid-sensor-magn-3d.c +5 -3
@@ -163,21 +163,23 @@ static int magn_3d_read_raw(struct iio_dev *indio_dev,int report_id =-1 ;u32 address;int ret_type; +s32 min; *val =0 ; *val2 =0 ;switch (mask) {case 0 :hid_sensor_power_state (&magn_state->magn_flux_attributes, true); - report_id = - magn_state->magn[chan->address].report_id; + report_id = magn_state->magn[chan->address].report_id; + min = magn_state->magn[chan->address].logical_minimum; address = magn_3d_addresses[chan->address];if (report_id >=0 ) *val =sensor_hub_input_attr_get_raw_value ( magn_state->magn_flux_attributes.hsdev,HID_USAGE_SENSOR_COMPASS_3D , address, report_id, -SENSOR_HUB_SYNC ); +SENSOR_HUB_SYNC , + min <0 );else { *val =0 ; hid_sensor_power_state(
drivers/iio/orientation/hid-sensor-incl-3d.c +5 -3
@@ -111,21 +111,23 @@ static int incl_3d_read_raw(struct iio_dev *indio_dev,int report_id =-1 ;u32 address;int ret_type; +s32 min; *val =0 ; *val2 =0 ;switch (mask) {case IIO_CHAN_INFO_RAW :hid_sensor_power_state (&incl_state->common_attributes, true); - report_id = - incl_state->incl[chan->scan_index].report_id; + report_id = incl_state->incl[chan->scan_index].report_id; + min = incl_state->incl[chan->scan_index].logical_minimum; address = incl_3d_addresses[chan->scan_index];if (report_id >=0 ) *val =sensor_hub_input_attr_get_raw_value ( incl_state->common_attributes.hsdev,HID_USAGE_SENSOR_INCLINOMETER_3D , address, report_id, -SENSOR_HUB_SYNC ); +SENSOR_HUB_SYNC , + min <0 );else {hid_sensor_power_state (&incl_state->common_attributes, false);
drivers/iio/pressure/hid-sensor-press.c +5 -3
@@ -77,6 +77,7 @@ static int press_read_raw(struct iio_dev *indio_dev,int report_id =-1 ;u32 address;int ret_type; +s32 min; *val =0 ; *val2 =0 ;
@@ -85,8 +86,8 @@ static int press_read_raw(struct iio_dev *indio_dev,switch (chan->scan_index) {case CHANNEL_SCAN_INDEX_PRESSURE : report_id = press_state->press_attr.report_id; - address = -HID_USAGE_SENSOR_ATMOSPHERIC_PRESSURE ; + min = press_state->press_attr.logical_minimum; + address =HID_USAGE_SENSOR_ATMOSPHERIC_PRESSURE ;break ;default : report_id =-1 ;
@@ -99,7 +100,8 @@ static int press_read_raw(struct iio_dev *indio_dev, press_state->common_attributes.hsdev,HID_USAGE_SENSOR_PRESSURE , address, report_id, - SENSOR_HUB_SYNC); +SENSOR_HUB_SYNC , + min < 0);hid_sensor_power_state (&press_state->common_attributes, false); }else {
drivers/iio/temperature/hid-sensor-temperature.c +2 -1
@@ -76,7 +76,8 @@ static int temperature_read_raw(struct iio_dev *indio_dev,HID_USAGE_SENSOR_TEMPERATURE ,HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE , temp_st->temperature_attr.report_id, - SENSOR_HUB_SYNC); +SENSOR_HUB_SYNC , + temp_st->temperature_attr.logical_minimum < 0);hid_sensor_power_state ( &temp_st->common_attributes, false);
drivers/rtc/rtc-hid-sensor-time.c +1 -1
@@ -213,7 +213,7 @@ static int hid_rtc_read_time(struct device *dev, struct rtc_time *tm)/* get a report with all values through requesting one value */ sensor_hub_input_attr_get_raw_value (time_state->common_attributes.hsdev,HID_USAGE_SENSOR_TIME , hid_time_addresses[0 ], - time_state->info[0 ].report_id,SENSOR_HUB_SYNC ); + time_state->info[0 ].report_id,SENSOR_HUB_SYNC , false);/* wait for all values (event) */ ret =wait_for_completion_killable_timeout ( &time_state->comp_last_time,HZ *6 );
include/linux/hid-sensor-hub.h +3 -1
@@ -177,6 +177,7 @@ int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev,* @attr_usage_id: Attribute usage id as per spec * @report_id: Report id to look for * @flag: Synchronous or asynchronous read +* @is_signed: If true then fields < 32 bits will be sign-extended * * Issues a synchronous or asynchronous read request for an input attribute. * Returns data upto 32 bits.
@@ -190,7 +191,8 @@ enum sensor_hub_read_flags {int sensor_hub_input_attr_get_raw_value (struct hid_sensor_hub_device *hsdev,u32 usage_id,u32 attr_usage_id,u32 report_id, -enum sensor_hub_read_flags flag +enum sensor_hub_read_flags flag, +bool is_signed );/**
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 17/69 netfilter: xt_hashlimit: fix a possible memory leak in htable_create()
In reply to Sasha LevinFrom: Taehee Yoo <[email protected]>
[ Upstream commit b4e955e9f372035361fbc6f07b21fe2cc6a5be4a ]
In the htable_create(), hinfo is allocated by vmalloc() So that if error occurred, hinfo should be freed.
--- net/netfilter/xt_hashlimit.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
net/netfilter/xt_hashlimit.c +3 -6
@@ -295,9 +295,10 @@ static int htable_create(struct net *net, struct hashlimit_cfg3 *cfg,/* copy match config into hashtable config */ ret =cfg_copy (&hinfo->cfg, (void *)cfg,3 ); - -if (ret) +if (ret) { +vfree (hinfo);return ret; + } hinfo->cfg.size = size;if (hinfo->cfg.max ==0 )
@@ -814,7 +815,6 @@ hashlimit_mt_v1(const struct sk_buff *skb, struct xt_action_param *par)int ret; ret =cfg_copy (&cfg, (void *)&info->cfg,1 ); -if (ret)return ret;
@@ -830,7 +830,6 @@ hashlimit_mt_v2(const struct sk_buff *skb, struct xt_action_param *par)int ret; ret =cfg_copy (&cfg, (void *)&info->cfg,2 ); -if (ret)return ret;
@@ -920,7 +919,6 @@ static int hashlimit_mt_check_v1(const struct xt_mtchk_param *par)return ret; ret =cfg_copy (&cfg, (void *)&info->cfg,1 ); -if (ret)return ret;
@@ -939,7 +937,6 @@ static int hashlimit_mt_check_v2(const struct xt_mtchk_param *par)return ret; ret =cfg_copy (&cfg, (void *)&info->cfg,2 ); -if (ret)return ret;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 18/69 hwmon: (w83795) temp4_type has writable permission
In reply to Sasha LevinFrom: Huacai Chen <[email protected]>
[ Upstream commit 09aaf6813cfca4c18034fda7a43e68763f34abb1 ]
Both datasheet and comments of store_temp_mode() tell us that temp1~4_type is writable, so fix it.
--- drivers/hwmon/w83795.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwmon/w83795.c +1 -1
@@ -1691,7 +1691,7 @@ store_sf_setup(struct device *dev, struct device_attribute *attr,* somewhere else in the code */ #define SENSOR_ATTR_TEMP (index) { \ - SENSOR_ATTR_2(temp##index##_type, S_IRUGO | (index < 4 ? S_IWUSR : 0), \ + SENSOR_ATTR_2(temp##index##_type, S_IRUGO | (index < 5 ? S_IWUSR : 0), \ show_temp_mode, store_temp_mode, NOT_USED, index - 1), \ SENSOR_ATTR_2(temp##index##_input, S_IRUGO, show_temp, \ NULL, TEMP_READ, index - 1), \
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 19/69 perf tools: Restore proper cwd on return from mnt namespace
In reply to Sasha LevinFrom: Jiri Olsa <[email protected]>
[ Upstream commit b01c1f69c8660eaeab7d365cd570103c5c073a02 ]
When reporting on 'record' server we try to retrieve/use the mnt namespace of the profiled tasks. We use following API with cookie to hold the return namespace, roughly:
nsinfo__mountns_enter(struct nsinfo *nsi, struct nscookie *nc)
setns(newns, 0);
...
new ns related open..
...
nsinfo__mountns_exit(struct nscookie *nc)
setns(nc->oldns)Once finished we setns to old namespace, which also sets the current working directory (cwd) to "/", trashing the cwd we had.
This is mostly fine, because we use absolute paths almost everywhere, but it screws up 'perf diff':
# perf diff failed to open perf.data: No such file or directory (try 'perf record' first) ...
Adding the current working directory to be part of the cookie and restoring it in the nsinfo__mountns_exit call.
--- tools/perf/util/namespaces.c | 17 +++++++++++++++-- tools/perf/util/namespaces.h | 1 + 2 files changed, 16 insertions(+), 2 deletions(-)
tools/perf/util/namespaces.c +15 -2
@@ -17,6 +17,7 @@#include <stdio.h> #include <string.h> #include <unistd.h> +#include <asm/bug.h> struct namespaces *namespaces__new (struct namespaces_event *event) {
@@ -185,6 +186,7 @@ void nsinfo__mountns_enter(struct nsinfo *nsi,char curpath[PATH_MAX ];int oldns =-1 ;int newns =-1 ; +char *oldcwd =NULL ;if (nc ==NULL )return ;
@@ -198,9 +200,13 @@ void nsinfo__mountns_enter(struct nsinfo *nsi,if (snprintf (curpath,PATH_MAX ,"/proc/self/ns/mnt" ) >=PATH_MAX )return ; + oldcwd =get_current_dir_name (); +if (!oldcwd) +return ; + oldns =open (curpath,O_RDONLY );if (oldns <0 ) -return ; + goto errout; newns =open (nsi->mntns_path,O_RDONLY );if (newns <0 )
@@ -209,11 +215,13 @@ void nsinfo__mountns_enter(struct nsinfo *nsi,if (setns (newns,CLONE_NEWNS ) <0 ) goto errout; + nc->oldcwd = oldcwd; nc->oldns = oldns; nc->newns = newns;return ; errout: +free (oldcwd);if (oldns >-1 )close (oldns);if (newns >-1 )
@@ -222,11 +230,16 @@ void nsinfo__mountns_enter(struct nsinfo *nsi,void nsinfo__mountns_exit (struct nscookie *nc) { -if (nc ==NULL || nc->oldns ==-1 || nc->newns ==-1 ) +if (nc ==NULL || nc->oldns ==-1 || nc->newns ==-1 || !nc->oldcwd)return ;setns (nc->oldns,CLONE_NEWNS ); +if (nc->oldcwd) { +WARN_ON_ONCE (chdir (nc->oldcwd)); +zfree (&nc->oldcwd); + } +if (nc->oldns >-1 ) {close (nc->oldns); nc->oldns =-1 ;
tools/perf/util/namespaces.h +1 -0
@@ -36,6 +36,7 @@ struct nsinfo {struct nscookie {int oldns;int newns; +char *oldcwd; };int nsinfo__init (struct nsinfo *nsi);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 20/69 PCI: imx6: Fix link training status detection in link up check
In reply to Sasha LevinFrom: Trent Piepho <[email protected]>
[ Upstream commit 68bc10bf992180f269816ff3d22eb30383138577 ]
This bug was introduced in the interaction for two commits on either branch of the merge commit 562df5c8521e ("Merge branch 'pci/host-designware' into next").
Commit 4d107d3b5a68 ("PCI: imx6: Move link up check into imx6_pcie_wait_for_link()"), changed imx6_pcie_wait_for_link() to poll the link status register directly, checking for link up and not training, and made imx6_pcie_link_up() only check the link up bit (once, not a polling loop).
While commit 886bc5ceb5cc ("PCI: designware: Add generic dw_pcie_wait_for_link()"), replaced the loop in imx6_pcie_wait_for_link() with a call to a new dwc core function, which polled imx6_pcie_link_up(), which still checked both link up and not training in a loop.
When these two commits were merged, the version of imx6_pcie_wait_for_link() from 886bc5ceb5cc was kept, which eliminated the link training check placed there by 4d107d3b5a68. However, the version of imx6_pcie_link_up() from 4d107d3b5a68 was kept, which eliminated the link training check that had been there and was moved to imx6_pcie_wait_for_link().
The result was the link training check got lost for the imx6 driver.
Eliminate imx6_pcie_link_up() so that the default handler, dw_pcie_link_up(), is used instead. The default handler has the correct code, which checks for link up and also that it still is not training, fixing the regression.
--- drivers/pci/dwc/pci-imx6.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-)
drivers/pci/dwc/pci-imx6.c +1 -9
@@ -83,8 +83,6 @@ struct imx6_pcie {#define PCIE_PL_PFLR_FORCE_LINK (1 << 15)#define PCIE_PHY_DEBUG_R0 (PL_OFFSET + 0x28)#define PCIE_PHY_DEBUG_R1 (PL_OFFSET + 0x2c) -#define PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING (1 << 29) -#define PCIE_PHY_DEBUG_R1_XMLH_LINK_UP (1 << 4)#define PCIE_PHY_CTRL (PL_OFFSET + 0x114)#define PCIE_PHY_CTRL_DATA_LOC 0
@@ -653,12 +651,6 @@ static int imx6_pcie_host_init(struct pcie_port *pp)return 0 ; } -static int imx6_pcie_link_up (struct dw_pcie *pci) -{ -return dw_pcie_readl_dbi (pci,PCIE_PHY_DEBUG_R1 ) & -PCIE_PHY_DEBUG_R1_XMLH_LINK_UP ; -} -static const struct dw_pcie_host_ops imx6_pcie_host_ops = { .host_init = imx6_pcie_host_init, };
@@ -701,7 +693,7 @@ static int imx6_add_pcie_port(struct imx6_pcie *imx6_pcie, }static const struct dw_pcie_ops dw_pcie_ops = { - .link_up = imx6_pcie_link_up, +/* No special ops needed, but pcie-designware still expects this struct */ };static int imx6_pcie_probe (struct platform_device *pdev)
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 21/69 objtool: Fix double-free in .cold detection error path
In reply to Sasha LevinFrom: Artem Savkov <[email protected]>
[ Upstream commit 0b9301fb632f7111a3293a30cc5b20f1b82ed08d ]
If read_symbols() fails during second list traversal (the one dealing with ".cold" subfunctions) it frees the symbol, but never deletes it from the list/hash_table resulting in symbol being freed again in elf_close(). Fix it by just returning an error, leaving cleanup to elf_close().
--- tools/objtool/elf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/objtool/elf.c +1 -1
@@ -312,7 +312,7 @@ static int read_symbols(struct elf *elf)if (!pfunc) {WARN ("%s(): can't find parent function" , sym->name); - goto err; +return -1 ; } sym->pfunc = pfunc;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 22/69 objtool: Fix segfault in .cold detection with -ffunction-sections
In reply to Sasha LevinFrom: Artem Savkov <[email protected]>
[ Upstream commit 22566c1603030f0a036ad564634b064ad1a55db2 ]
Because find_symbol_by_name() traverses the same lists as read_symbols(), changing sym->name in place without copying it affects the result of find_symbol_by_name(). In the case where a ".cold" function precedes its parent in sec->symbol_list, it can result in a function being considered a parent of itself. This leads to function length being set to 0 and other consequent side-effects including a segfault in add_switch_table(). The effects of this bug are only visible when building with -ffunction-sections in KCFLAGS.
Fix by copying the search string instead of modifying it in place.
--- tools/objtool/elf.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
tools/objtool/elf.c +14 -3
@@ -31,6 +31,8 @@#include "elf.h" #include "warn.h" +#define MAX_NAME_LEN 128 +struct section *find_section_by_name (struct elf *elf,const char *name) {struct section *sec;
@@ -298,6 +300,8 @@ static int read_symbols(struct elf *elf)/* Create parent/child links for any cold subfunctions */ list_for_each_entry (sec, &elf->sections, list) {list_for_each_entry (sym, &sec->symbol_list, list) { +char pname[MAX_NAME_LEN +1 ]; +size_t pnamelen;if (sym->type !=STT_FUNC )continue ; sym->pfunc = sym->cfunc = sym;
@@ -305,9 +309,16 @@ static int read_symbols(struct elf *elf)if (!coldstr)continue ; - coldstr[0 ] ='\0' ; - pfunc =find_symbol_by_name (elf, sym->name); - coldstr[0 ] ='.' ; + pnamelen = coldstr - sym->name; +if (pnamelen >MAX_NAME_LEN ) { +WARN ("%s(): parent function name exceeds maximum length of %d characters" , + sym->name,MAX_NAME_LEN ); +return -1 ; + } + +strncpy (pname, sym->name, pnamelen); + pname[pnamelen] ='\0' ; + pfunc =find_symbol_by_name (elf, pname);if (!pfunc) { WARN("%s(): can't find parent function",
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 23/69 ARM: dts: at91: sama5d2: use the divided clock for SMC
In reply to Sasha LevinFrom: Romain Izard <[email protected]>
[ Upstream commit 4ab7ca092c3c7ac8b16aa28eba723a8868f82f14 ]
The SAMA5D2 is different from SAMA5D3 and SAMA5D4, as there are two different clocks for the peripherals in the SoC. The Static Memory controller is connected to the divided master clock.
Unfortunately, the device tree does not correctly show this and uses the master clock directly. This clock is then used by the code for the NAND controller to calculate the timings for the controller, and we end up with slow NAND Flash access.
Fix the device tree, and the performance of Flash access is improved.
--- arch/arm/boot/dts/sama5d2.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/sama5d2.dtsi +1 -1
@@ -308,7 +308,7 @@ 0x1 0x0 0x60000000 0x10000000 0x2 0x0 0x70000000 0x10000000 0x3 0x0 0x80000000 0x10000000>; - clocks = <&mck>; + clocks = <&h32ck>; status = "disabled"; nand_controller: nand-controller {
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 24/69 Btrfs: send, fix infinite loop due to directory rename dependencies
In reply to Sasha LevinFrom: Robbie Ko <[email protected]>
[ Upstream commit a4390aee72713d9e73f1132bcdeb17d72fbbf974 ]
When doing an incremental send, due to the need of delaying directory move (rename) operations we can end up in infinite loop at apply_children_dir_moves().
An example scenario that triggers this problem is described below, where directory names correspond to the numbers of their respective inodes.
Parent snapshot:
.
|--- 261/
|--- 271/
|--- 266/
|--- 259/
|--- 260/
| |--- 267
|
|--- 264/
| |--- 258/
| |--- 257/
|
|--- 265/
|--- 268/
|--- 269/
| |--- 262/
|
|--- 270/
|--- 272/
| |--- 263/
| |--- 275/
|
|--- 274/
|--- 273/Send snapshot:
.
|-- 275/
|-- 274/
|-- 273/
|-- 262/
|-- 269/
|-- 258/
|-- 271/
|-- 268/
|-- 267/
|-- 270/
|-- 259/
| |-- 265/
|
|-- 272/
|-- 257/
|-- 260/
|-- 264/
|-- 263/
|-- 261/
|-- 266/When processing inode 257 we delay its move (rename) operation because its new parent in the send snapshot, inode 272, was not yet processed. Then when processing inode 272, we delay the move operation for that inode because inode 274 is its ancestor in the send snapshot. Finally we delay the move operation for inode 274 when processing it because inode 275 is its new parent in the send snapshot and was not yet moved.
When finishing processing inode 275, we start to do the move operations that were previously delayed (at apply_children_dir_moves()), resulting in the following iterations:
1) We issue the move operation for inode 274;
2) Because inode 262 depended on the move operation of inode 274 (it was delayed because 274 is its ancestor in the send snapshot), we issue the move operation for inode 262;
3) We issue the move operation for inode 272, because it was delayed by inode 274 too (ancestor of 272 in the send snapshot);
4) We issue the move operation for inode 269 (it was delayed by 262);
5) We issue the move operation for inode 257 (it was delayed by 272);
6) We issue the move operation for inode 260 (it was delayed by 272);
7) We issue the move operation for inode 258 (it was delayed by 269);
8) We issue the move operation for inode 264 (it was delayed by 257);
9) We issue the move operation for inode 271 (it was delayed by 258);
10) We issue the move operation for inode 263 (it was delayed by 264);
11) We issue the move operation for inode 268 (it was delayed by 271);
12) We verify if we can issue the move operation for inode 270 (it was delayed by 271). We detect a path loop in the current state, because inode 267 needs to be moved first before we can issue the move operation for inode 270. So we delay again the move operation for inode 270, this time we will attempt to do it after inode 267 is moved;
13) We issue the move operation for inode 261 (it was delayed by 263);
14) We verify if we can issue the move operation for inode 266 (it was delayed by 263). We detect a path loop in the current state, because inode 270 needs to be moved first before we can issue the move operation for inode 266. So we delay again the move operation for inode 266, this time we will attempt to do it after inode 270 is moved (its move operation was delayed in step 12);
15) We issue the move operation for inode 267 (it was delayed by 268);
16) We verify if we can issue the move operation for inode 266 (it was delayed by 270). We detect a path loop in the current state, because inode 270 needs to be moved first before we can issue the move operation for inode 266. So we delay again the move operation for inode 266, this time we will attempt to do it after inode 270 is moved (its move operation was delayed in step 12). So here we added again the same delayed move operation that we added in step 14;
17) We attempt again to see if we can issue the move operation for inode 266, and as in step 16, we realize we can not due to a path loop in the current state due to a dependency on inode 270. Again we delay inode's 266 rename to happen after inode's 270 move operation, adding the same dependency to the empty stack that we did in steps 14 and 16. The next iteration will pick the same move dependency on the stack (the only entry) and realize again there is still a path loop and then again the same dependency to the stack, over and over, resulting in an infinite loop.
So fix this by preventing adding the same move dependency entries to the stack by removing each pending move record from the red black tree of pending moves. This way the next call to get_pending_dir_moves() will not return anything for the current parent inode.
A test case for fstests, with this reproducer, follows soon.
--- fs/btrfs/send.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
fs/btrfs/send.c +8 -3
@@ -3354,7 +3354,8 @@ static void free_pending_move(struct send_ctx *sctx, struct pending_dir_move *m)kfree (m); } -static void tail_append_pending_moves (struct pending_dir_move *moves, +static void tail_append_pending_moves (struct send_ctx *sctx, +struct pending_dir_move *moves,struct list_head *stack) {if (list_empty (&moves->list)) {
@@ -3365,6 +3366,10 @@ static void tail_append_pending_moves(struct pending_dir_move *moves,list_add_tail (&moves->list, stack);list_splice_tail (&list, stack); } +if (!RB_EMPTY_NODE (&moves->node)) { +rb_erase (&moves->node, &sctx->pending_dir_moves); +RB_CLEAR_NODE (&moves->node); + } }static int apply_children_dir_moves (struct send_ctx *sctx)
@@ -3379,7 +3384,7 @@ static int apply_children_dir_moves(struct send_ctx *sctx)return 0 ;INIT_LIST_HEAD (&stack); -tail_append_pending_moves (pm, &stack); +tail_append_pending_moves (sctx, pm, &stack);while (!list_empty (&stack)) { pm = list_first_entry(&stack, struct pending_dir_move, list);
@@ -3390,7 +3395,7 @@ static int apply_children_dir_moves(struct send_ctx *sctx) goto out; pm =get_pending_dir_moves (sctx, parent_ino);if (pm) -tail_append_pending_moves (pm, &stack); +tail_append_pending_moves (sctx, pm, &stack); }return 0 ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 25/69 RDMA/mlx5: Fix fence type for IB_WR_LOCAL_INV WR
In reply to Sasha LevinFrom: Majd Dibbiny <[email protected]>
[ Upstream commit 074fca3a18e7e1e0d4d7dcc9d7badc43b90232f4 ]
Currently, for IB_WR_LOCAL_INV WR, when the next fence is None, the current fence will be SMALL instead of Normal Fence.
Without this patch krping doesn't work on CX-5 devices and throws following error:
The error messages are from CX5 driver are: (from server side)
[ 710.434014] mlx5_0:dump_cqe:278:(pid 2712): dump error cqe [ 710.434016] 00000000 00000000 00000000 00000000 [ 710.434016] 00000000 00000000 00000000 00000000 [ 710.434017] 00000000 00000000 00000000 00000000 [ 710.434018] 00000000 93003204 100000b8 000524d2 [ 710.434019] krping: cq completion failed with wr_id 0 status 4 opcode 128 vender_err 32
Fixed the logic to set the correct fence type.
--- drivers/infiniband/hw/mlx5/qp.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
drivers/infiniband/hw/mlx5/qp.c +10 -9
@@ -3928,17 +3928,18 @@ int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, goto out; } -if (wr->opcode ==IB_WR_LOCAL_INV || - wr->opcode ==IB_WR_REG_MR ) { +if (wr->opcode ==IB_WR_REG_MR ) { fence = dev->umr_fence; next_fence =MLX5_FENCE_MODE_INITIATOR_SMALL ; - }else if (wr->send_flags &IB_SEND_FENCE ) { -if (qp->next_fence) - fence =MLX5_FENCE_MODE_SMALL_AND_FENCE ; -else - fence =MLX5_FENCE_MODE_FENCE ; - }else { - fence = qp->next_fence; + }else { +if (wr->send_flags &IB_SEND_FENCE ) { +if (qp->next_fence) + fence =MLX5_FENCE_MODE_SMALL_AND_FENCE ; +else + fence =MLX5_FENCE_MODE_FENCE ; + }else { + fence = qp->next_fence; + } }switch (ibqp->qp_type) {
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 26/69 RDMA/rdmavt: Fix rvt_create_ah function signature
In reply to Sasha LevinFrom: Kamal Heib <[email protected]>
[ Upstream commit 4f32fb921b153ae9ea280e02a3e91509fffc03d3 ]
rdmavt uses a crazy system that looses the type checking when assinging functions to struct ib_device function pointers. Because of this the signature to this function was not changed when the below commit revised things.
Fix the signature so we are not calling a function pointer with a mismatched signature.
--- drivers/infiniband/sw/rdmavt/ah.c | 4 +++- drivers/infiniband/sw/rdmavt/ah.h | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-)
drivers/infiniband/sw/rdmavt/ah.c +3 -1
@@ -91,13 +91,15 @@ EXPORT_SYMBOL(rvt_check_ah);* rvt_create_ah - create an address handle * @pd: the protection domain * @ah_attr: the attributes of the AH +* @udata: pointer to user's input output buffer information. * * This may be called from interrupt context. * * Return: newly allocated ah */ struct ib_ah *rvt_create_ah (struct ib_pd *pd, -struct rdma_ah_attr *ah_attr) +struct rdma_ah_attr *ah_attr, +struct ib_udata *udata) {struct rvt_ah *ah;struct rvt_dev_info *dev =ib_to_rvt (pd->device);
drivers/infiniband/sw/rdmavt/ah.h +2 -1
@@ -51,7 +51,8 @@#include <rdma/rdma_vt.h> struct ib_ah *rvt_create_ah (struct ib_pd *pd, -struct rdma_ah_attr *ah_attr); +struct rdma_ah_attr *ah_attr, +struct ib_udata *udata);int rvt_destroy_ah (struct ib_ah *ibah);int rvt_modify_ah (struct ib_ah *ibah,struct rdma_ah_attr *ah_attr);int rvt_query_ah (struct ib_ah *ibah,struct rdma_ah_attr *ah_attr);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 27/69 uprobes: Fix handle_swbp() vs. unregister() + register() race once more
In reply to Sasha LevinFrom: Andrea Parri <[email protected]>
[ Upstream commit 09d3f015d1e1b4fee7e9bbdcf54201d239393391 ]
Commit:
142b18ddc8143 ("uprobes: Fix handle_swbp() vs unregister() + register() race")
added the UPROBE_COPY_INSN flag, and corresponding smp_wmb() and smp_rmb() memory barriers, to ensure that handle_swbp() uses fully-initialized uprobes only.
However, the smp_rmb() is mis-placed: this barrier should be placed after handle_swbp() has tested for the flag, thus guaranteeing that (program-order) subsequent loads from the uprobe can see the initial stores performed by prepare_uprobe().
Move the smp_rmb() accordingly. Also amend the comments associated to the two memory barriers to indicate their actual locations.
--- kernel/events/uprobes.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
kernel/events/uprobes.c +10 -2
@@ -616,7 +616,7 @@ static int prepare_uprobe(struct uprobe *uprobe, struct file *file,BUG_ON ((uprobe->offset & ~PAGE_MASK ) +UPROBE_SWBP_INSN_SIZE >PAGE_SIZE ); -smp_wmb ();/* pairs with rmb() in find_active_uprobe() */ +smp_wmb ();/* pairs with the smp_rmb() in handle_swbp() */ set_bit (UPROBE_COPY_INSN , &uprobe->flags); out:
@@ -1910,10 +1910,18 @@ static void handle_swbp(struct pt_regs *regs)* After we hit the bp, _unregister + _register can install the * new and not-yet-analyzed uprobe at the same address, restart. */ -smp_rmb ();/* pairs with wmb() in install_breakpoint() */ if (unlikely (!test_bit (UPROBE_COPY_INSN , &uprobe->flags))) goto out; +/* +* Pairs with the smp_wmb() in prepare_uprobe(). +* +* Guarantees that if we see the UPROBE_COPY_INSN bit set, then +* we must also see the stores to &uprobe->arch performed by the +* prepare_uprobe() call. +*/ +smp_rmb (); +/* Tracing handlers use ->utask to communicate with fetch methods */ if (!get_utask ()) goto out;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 28/69 ASoC: omap-mcbsp: Fix latency value calculation for pm_qos
In reply to Sasha LevinFrom: Peter Ujfalusi <[email protected]>
[ Upstream commit dd2f52d8991af9fe0928d59ec502ba52be7bc38d ]
The latency number is in usec for the pm_qos. Correct the calculation to give us the time in usec
--- sound/soc/omap/omap-mcbsp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
sound/soc/omap/omap-mcbsp.c +3 -3
@@ -308,9 +308,9 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, pkt_size = channels; } - latency = ((((buffer_size - pkt_size) / channels) *1000 ) - / (params->rate_num / params->rate_den)); - + latency = (buffer_size - pkt_size) / channels; + latency = latency *USEC_PER_SEC / + (params->rate_num / params->rate_den); mcbsp->latency[substream->stream] = latency;omap_mcbsp_set_threshold (substream, pkt_size);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 29/69 ASoC: omap-mcpdm: Add pm_qos handling to avoid under/overruns with CPU_IDLE
In reply to Sasha LevinFrom: Peter Ujfalusi <[email protected]>
[ Upstream commit 373a500e34aea97971c9d71e45edad458d3da98f ]
We need to block sleep states which would require longer time to leave than the time the DMA must react to the DMA request in order to keep the FIFO serviced without under of overrun.
--- sound/soc/omap/omap-mcpdm.c | 43 ++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-)
sound/soc/omap/omap-mcpdm.c +42 -1
@@ -54,6 +54,8 @@ struct omap_mcpdm {unsigned long phys_base;void __iomem *io_base;int irq; +struct pm_qos_request pm_qos_req; +int latency[2 ];struct mutex mutex;
@@ -277,6 +279,9 @@ static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) {struct omap_mcpdm *mcpdm =snd_soc_dai_get_drvdata (dai); +int tx = (substream->stream ==SNDRV_PCM_STREAM_PLAYBACK ); +int stream1 = tx ?SNDRV_PCM_STREAM_PLAYBACK :SNDRV_PCM_STREAM_CAPTURE ; +int stream2 = tx ?SNDRV_PCM_STREAM_CAPTURE :SNDRV_PCM_STREAM_PLAYBACK ;mutex_lock (&mcpdm->mutex);
@@ -289,6 +294,14 @@ static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream, } } +if (mcpdm->latency[stream2]) +pm_qos_update_request (&mcpdm->pm_qos_req, + mcpdm->latency[stream2]); +else if (mcpdm->latency[stream1]) +pm_qos_remove_request (&mcpdm->pm_qos_req); + + mcpdm->latency[stream1] =0 ; +mutex_unlock (&mcpdm->mutex); }
@@ -300,7 +313,7 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,int stream = substream->stream;struct snd_dmaengine_dai_dma_data *dma_data;u32 threshold; -int channels; +int channels, latency;int link_mask =0 ; channels =params_channels (params);
@@ -340,14 +353,25 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, dma_data->maxburst = (MCPDM_DN_THRES_MAX - threshold) * channels; + latency = threshold; }else {/* If playback is not running assume a stereo stream to come */ if (!mcpdm->config[!stream].link_mask) mcpdm->config[!stream].link_mask = (0x3 <<3 ); dma_data->maxburst = threshold * channels; + latency = (MCPDM_DN_THRES_MAX - threshold); } +/* +* The DMA must act to a DMA request within latency time (usec) to avoid +* under/overflow +*/ + mcpdm->latency[stream] = latency *USEC_PER_SEC /params_rate (params); + +if (!mcpdm->latency[stream]) + mcpdm->latency[stream] =10 ; +/* Check if we need to restart McPDM with this stream */ if (mcpdm->config[stream].link_mask && mcpdm->config[stream].link_mask != link_mask)
@@ -362,6 +386,20 @@ static int omap_mcpdm_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) {struct omap_mcpdm *mcpdm =snd_soc_dai_get_drvdata (dai); +struct pm_qos_request *pm_qos_req = &mcpdm->pm_qos_req; +int tx = (substream->stream ==SNDRV_PCM_STREAM_PLAYBACK ); +int stream1 = tx ?SNDRV_PCM_STREAM_PLAYBACK :SNDRV_PCM_STREAM_CAPTURE ; +int stream2 = tx ?SNDRV_PCM_STREAM_CAPTURE :SNDRV_PCM_STREAM_PLAYBACK ; +int latency = mcpdm->latency[stream2]; + +/* Prevent omap hardware from hitting off between FIFO fills */ +if (!latency || mcpdm->latency[stream1] < latency) + latency = mcpdm->latency[stream1]; + +if (pm_qos_request_active (pm_qos_req)) +pm_qos_update_request (pm_qos_req, latency); +else if (latency) +pm_qos_add_request (pm_qos_req,PM_QOS_CPU_DMA_LATENCY , latency);if (!omap_mcpdm_active (mcpdm)) {omap_mcpdm_start (mcpdm);
@@ -423,6 +461,9 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai)free_irq (mcpdm->irq, (void *)mcpdm);pm_runtime_disable (mcpdm->dev); +if (pm_qos_request_active (&mcpdm->pm_qos_req)) +pm_qos_remove_request (&mcpdm->pm_qos_req); +return 0 ; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 30/69 ASoC: omap-dmic: Add pm_qos handling to avoid overruns with CPU_IDLE
In reply to Sasha LevinFrom: Peter Ujfalusi <[email protected]>
[ Upstream commit ffdcc3638c58d55a6fa68b6e5dfd4fb4109652eb ]
We need to block sleep states which would require longer time to leave than the time the DMA must react to the DMA request in order to keep the FIFO serviced without overrun.
--- sound/soc/omap/omap-dmic.c | 9 +++++++++ 1 file changed, 9 insertions(+)
sound/soc/omap/omap-dmic.c +9 -0
@@ -48,6 +48,8 @@ struct omap_dmic {struct device *dev;void __iomem *io_base;struct clk *fclk; +struct pm_qos_request pm_qos_req; +int latency;int fclk_freq;int out_freq;int clk_div;
@@ -124,6 +126,8 @@ static void omap_dmic_dai_shutdown(struct snd_pcm_substream *substream,mutex_lock (&dmic->mutex); +pm_qos_remove_request (&dmic->pm_qos_req); +if (!dai->active) dmic->active =0 ;
@@ -226,6 +230,8 @@ static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream,/* packet size is threshold * channels */ dma_data =snd_soc_dai_get_dma_data (dai, substream); dma_data->maxburst = dmic->threshold * channels; + dmic->latency = (OMAP_DMIC_THRES_MAX - dmic->threshold) *USEC_PER_SEC / +params_rate (params);return 0 ; }
@@ -236,6 +242,9 @@ static int omap_dmic_dai_prepare(struct snd_pcm_substream *substream,struct omap_dmic *dmic =snd_soc_dai_get_drvdata (dai);u32 ctrl; +if (pm_qos_request_active (&dmic->pm_qos_req)) +pm_qos_update_request (&dmic->pm_qos_req, dmic->latency); +/* Configure uplink threshold */ omap_dmic_write (dmic,OMAP_DMIC_FIFO_CTRL_REG , dmic->threshold);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 31/69 exportfs: do not read dentry after free
In reply to Sasha LevinFrom: Pan Bian <[email protected]>
[ Upstream commit 2084ac6c505a58f7efdec13eba633c6aaa085ca5 ]
The function dentry_connected calls dput(dentry) to drop the previously acquired reference to dentry. In this case, dentry can be released. After that, IS_ROOT(dentry) checks the condition
(dentry == dentry->d_parent), which may result in a use-after-free bug. This patch directly compares dentry with its parent obtained before dropping the reference.
rename/remove")
--- fs/exportfs/expfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/exportfs/expfs.c +1 -1
@@ -77,7 +77,7 @@ static bool dentry_connected(struct dentry *dentry)struct dentry *parent =dget_parent (dentry);dput (dentry); -if (IS_ROOT (dentry)) { +if (dentry == parent) {dput (parent);return false; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 32/69 bpf: fix check of allowed specifiers in bpf_trace_printk
In reply to Sasha LevinFrom: Martynas Pumputis <[email protected]>
[ Upstream commit 1efb6ee3edea57f57f9fb05dba8dcb3f7333f61f ]
A format string consisting of "%p" or "%s" followed by an invalid specifier (e.g. "%p%\n" or "%s%") could pass the check which would make format_decode (lib/vsprintf.c) to warn.
--- kernel/trace/bpf_trace.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
kernel/trace/bpf_trace.c +5 -3
@@ -161,11 +161,13 @@ BPF_CALL_5(bpf_trace_printk, char *, fmt, u32, fmt_size, u64, arg1, i++; }else if (fmt[i] =='p' || fmt[i] =='s' ) { mod[fmt_cnt]++; - i++; -if (!isspace (fmt[i]) && !ispunct (fmt[i]) && fmt[i] !=0 ) +/* disallow any further format extensions */ +if (fmt[i +1 ] !=0 && + !isspace (fmt[i +1 ]) && + !ispunct (fmt[i +1 ]))return -EINVAL ; fmt_cnt++; -if (fmt[i -1 ] =='s' ) { +if (fmt[i] =='s' ) {if (str_seen)/* allow only one '%s' per fmt string */ return -EINVAL ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 33/69 ipvs: call ip_vs_dst_notifier earlier than ipv6_dev_notf
In reply to Sasha LevinFrom: Xin Long <[email protected]>
[ Upstream commit 2a31e4bd9ad255ee40809b5c798c4b1c2b09703b ]
ip_vs_dst_event is supposed to clean up all dst used in ipvs' destinations when a net dev is going down. But it works only when the dst's dev is the same as the dev from the event.
Now with the same priority but late registration, ip_vs_dst_notifier is always called later than ipv6_dev_notf where the dst's dev is set to lo for NETDEV_DOWN event.
As the dst's dev lo is not the same as the dev from the event in ip_vs_dst_event, ip_vs_dst_notifier doesn't actually work. Also as these dst have to wait for dest_trash_timer to clean them up. It would cause some non-permanent kernel warnings:
unregister_netdevice: waiting for br0 to become free. Usage count = 3
To fix it, call ip_vs_dst_notifier earlier than ipv6_dev_notf by increasing its priority to ADDRCONF_NOTIFY_PRIORITY + 5.
Note that for ipv4 route fib_netdev_notifier doesn't set dst's dev to lo in NETDEV_DOWN event, so this fix is only needed when IP_VS_IPV6 is defined.
--- net/netfilter/ipvs/ip_vs_ctl.c | 3 +++ 1 file changed, 3 insertions(+)
net/netfilter/ipvs/ip_vs_ctl.c +3 -0
@@ -4012,6 +4012,9 @@ static void __net_exit ip_vs_control_net_cleanup_sysctl(struct netns_ipvs *ipvs)static struct notifier_block ip_vs_dst_notifier = { .notifier_call = ip_vs_dst_event, +#ifdef CONFIG_IP_VS_IPV6 + .priority =ADDRCONF_NOTIFY_PRIORITY +5 , +#endif };int __net_init ip_vs_control_net_init (struct netns_ipvs *ipvs)
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 34/69 USB: omap_udc: use devm_request_irq()
In reply to Sasha LevinFrom: Aaro Koskinen <[email protected]>
[ Upstream commit 286afdde1640d8ea8916a0f05e811441fbbf4b9d ]
The current code fails to release the third irq on the error path (observed by reading the code), and we get also multiple WARNs with failing gadget drivers due to duplicate IRQ releases. Fix by using devm_request_irq().
--- drivers/usb/gadget/udc/omap_udc.c | 37 +++++++++---------------------- 1 file changed, 10 insertions(+), 27 deletions(-)
drivers/usb/gadget/udc/omap_udc.c +10 -27
@@ -2886,8 +2886,8 @@ static int omap_udc_probe(struct platform_device *pdev) udc->clr_halt =UDC_RESET_EP ;/* USB general purpose IRQ: ep0, state changes, dma, etc */ - status =request_irq (pdev->resource[1 ].start, omap_udc_irq, -0 , driver_name, udc); + status =devm_request_irq (&pdev->dev, pdev->resource[1 ].start, + omap_udc_irq,0 , driver_name, udc);if (status !=0 ) {ERR ("can't get irq %d, err %d\n" , (int ) pdev->resource[1 ].start, status);
@@ -2895,20 +2895,20 @@ static int omap_udc_probe(struct platform_device *pdev) }/* USB "non-iso" IRQ (PIO for all but ep0) */ - status =request_irq (pdev->resource[2 ].start, omap_udc_pio_irq, -0 ,"omap_udc pio" , udc); + status =devm_request_irq (&pdev->dev, pdev->resource[2 ].start, + omap_udc_pio_irq,0 ,"omap_udc pio" , udc);if (status !=0 ) {ERR ("can't get irq %d, err %d\n" , (int ) pdev->resource[2 ].start, status); - goto cleanup2; + goto cleanup1; }#ifdef USE_ISO - status =request_irq (pdev->resource[3 ].start, omap_udc_iso_irq, -0 ,"omap_udc iso" , udc); + status =devm_request_irq (&pdev->dev, pdev->resource[3 ].start, + omap_udc_iso_irq,0 ,"omap_udc iso" , udc);if (status !=0 ) {ERR ("can't get irq %d, err %d\n" , (int ) pdev->resource[3 ].start, status); - goto cleanup3; + goto cleanup1; }#endif if (cpu_is_omap16xx () ||cpu_is_omap7xx ()) {
@@ -2921,22 +2921,11 @@ static int omap_udc_probe(struct platform_device *pdev)create_proc_file (); status =usb_add_gadget_udc_release (&pdev->dev, &udc->gadget, omap_udc_release); -if (status) - goto cleanup4; - -return 0 ; +if (!status) +return 0 ; -cleanup4:remove_proc_file (); -#ifdef USE_ISO -cleanup3: -free_irq (pdev->resource[2 ].start, udc); -#endif - -cleanup2: -free_irq (pdev->resource[1 ].start, udc); - cleanup1:kfree (udc); udc =NULL ;
@@ -2980,12 +2969,6 @@ static int omap_udc_remove(struct platform_device *pdev)remove_proc_file (); -#ifdef USE_ISO -free_irq (pdev->resource[3 ].start, udc); -#endif -free_irq (pdev->resource[2 ].start, udc); -free_irq (pdev->resource[1 ].start, udc); -if (udc->dc_clk) {if (udc->clk_requested)omap_udc_enable_clock (0 );
Sasha Levin
maintainerPATCH 35/69 USB: omap_udc: fix crashes on probe error and module removal
In reply to Sasha LevinFrom: Aaro Koskinen <[email protected]>
[ Upstream commit 99f700366fcea1aa2fa3c49c99f371670c3c62f8 ]
We currently crash if usb_add_gadget_udc_release() fails, since the udc->done is not initialized until in the remove function. Furthermore, on module removal the udc data is accessed although the release function is already triggered by usb_del_gadget_udc() early in the function.
Fix by rewriting the release and remove functions, basically moving all the cleanup into the release function, and doing the completion only in the module removal case.
The patch fixes omap_udc module probe with a failing gadged, and also allows the removal of omap_udc. Tested by running "modprobe omap_udc; modprobe -r omap_udc" in a loop.
--- drivers/usb/gadget/udc/omap_udc.c | 50 ++++++++++++------------------- 1 file changed, 19 insertions(+), 31 deletions(-)
drivers/usb/gadget/udc/omap_udc.c +19 -31
@@ -2612,9 +2612,22 @@ omap_ep_setup(char *name, u8 addr, u8 type,static void omap_udc_release (struct device *dev) { -complete (udc->done); +pullup_disable (udc); +if (!IS_ERR_OR_NULL (udc->transceiver)) { +usb_put_phy (udc->transceiver); + udc->transceiver =NULL ; + } +omap_writew (0 ,UDC_SYSCON1 ); +remove_proc_file (); +if (udc->dc_clk) { +if (udc->clk_requested) +omap_udc_enable_clock (0 ); +clk_put (udc->hhc_clk); +clk_put (udc->dc_clk); + } +if (udc->done) +complete (udc->done);kfree (udc); - udc =NULL ; } static int
@@ -2919,12 +2932,8 @@ static int omap_udc_probe(struct platform_device *pdev) }create_proc_file (); - status =usb_add_gadget_udc_release (&pdev->dev, &udc->gadget, - omap_udc_release); -if (!status) -return 0 ; - -remove_proc_file (); +return usb_add_gadget_udc_release (&pdev->dev, &udc->gadget, + omap_udc_release); cleanup1:kfree (udc);
@@ -2951,36 +2960,15 @@ static int omap_udc_remove(struct platform_device *pdev) {DECLARE_COMPLETION_ONSTACK (done); -if (!udc) -return -ENODEV ; - -usb_del_gadget_udc (&udc->gadget); -if (udc->driver) -return -EBUSY ; - udc->done = &done; -pullup_disable (udc); -if (!IS_ERR_OR_NULL (udc->transceiver)) { -usb_put_phy (udc->transceiver); - udc->transceiver =NULL ; - } -omap_writew (0 ,UDC_SYSCON1 ); - -remove_proc_file (); +usb_del_gadget_udc (&udc->gadget); -if (udc->dc_clk) { -if (udc->clk_requested) -omap_udc_enable_clock (0 ); -clk_put (udc->hhc_clk); -clk_put (udc->dc_clk); - } +wait_for_completion (&done);release_mem_region (pdev->resource[0 ].start, pdev->resource[0 ].end - pdev->resource[0 ].start +1 ); -wait_for_completion (&done); -return 0 ; }
Sasha Levin
maintainerPATCH 36/69 USB: omap_udc: fix omap_udc_start() on 15xx machines
In reply to Sasha LevinFrom: Aaro Koskinen <[email protected]>
[ Upstream commit 6ca6695f576b8453fe68865e84d25946d63b10ad ]
On OMAP 15xx machines there are no transceivers, and omap_udc_start() always fails as it forgot to adjust the default return value.
--- drivers/usb/gadget/udc/omap_udc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/usb/gadget/udc/omap_udc.c +2 -1
@@ -2045,7 +2045,7 @@ static inline int machine_without_vbus_sense(void)static int omap_udc_start (struct usb_gadget *g,struct usb_gadget_driver *driver) { -int status = -ENODEV ; +int status;struct omap_ep *ep;unsigned long flags;
@@ -2083,6 +2083,7 @@ static int omap_udc_start(struct usb_gadget *g, goto done; } }else { + status =0 ;if (can_pullup (udc))pullup_enable (udc);else
Sasha Levin
maintainerPATCH 37/69 USB: omap_udc: fix USB gadget functionality on Palm Tungsten E
In reply to Sasha LevinFrom: Aaro Koskinen <[email protected]>
[ Upstream commit 2c2322fbcab8102b8cadc09d66714700a2da42c2 ]
On Palm TE nothing happens when you try to use gadget drivers and plug the USB cable. Fix by adding the board to the vbus sense quirk list.
--- drivers/usb/gadget/udc/omap_udc.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/gadget/udc/omap_udc.c +1 -0
@@ -2037,6 +2037,7 @@ static inline int machine_without_vbus_sense(void) {return machine_is_omap_innovator () ||machine_is_omap_osk () + ||machine_is_omap_palmte () ||machine_is_sx1 ()/* No known omap7xx boards with vbus sense */ ||cpu_is_omap7xx ();
Sasha Levin
maintainerPATCH 38/69 USB: omap_udc: fix rejection of out transfers when DMA is used
In reply to Sasha LevinFrom: Aaro Koskinen <[email protected]>
[ Upstream commit 069caf5950dfa75d0526cd89c439ff9d9d3136d8 ]
Commit 387f869d2579 ("usb: gadget: u_ether: conditionally align transfer size") started aligning transfer size only if requested, breaking omap_udc DMA mode. Set quirk_ep_out_aligned_size to restore the old behaviour.
--- drivers/usb/gadget/udc/omap_udc.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/gadget/udc/omap_udc.c +1 -0
@@ -2661,6 +2661,7 @@ omap_udc_setup(struct platform_device *odev, struct usb_phy *xceiv) udc->gadget.speed =USB_SPEED_UNKNOWN ; udc->gadget.max_speed =USB_SPEED_FULL ; udc->gadget.name = driver_name; + udc->gadget.quirk_ep_out_aligned_size =1 ; udc->transceiver = xceiv;/* ep0 is special; put it right after the SETUP buffer */
Sasha Levin
maintainerPATCH 39/69 drm/meson: add support for 1080p25 mode
In reply to Sasha LevinFrom: Christian Hewitt <[email protected]>
[ Upstream commit 31e1ab494559fb46de304cc6c2aed1528f94b298 ]
This essential mode for PAL users is missing, so add it.
--- drivers/gpu/drm/meson/meson_venc.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/meson/meson_venc.c +1 -0
@@ -714,6 +714,7 @@ struct meson_hdmi_venc_vic_mode { { 5, &meson_hdmi_encp_mode_1080i60 }, { 20, &meson_hdmi_encp_mode_1080i50 }, { 32, &meson_hdmi_encp_mode_1080p24 }, + { 33, &meson_hdmi_encp_mode_1080p50 }, { 34, &meson_hdmi_encp_mode_1080p30 }, { 31, &meson_hdmi_encp_mode_1080p50 }, { 16, &meson_hdmi_encp_mode_1080p60 },
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 40/69 netfilter: ipv6: Preserve link scope traffic original oif
In reply to Sasha LevinFrom: Alin Nastac <[email protected]>
[ Upstream commit 508b09046c0f21678652fb66fd1e9959d55591d2 ]
When ip6_route_me_harder is invoked, it resets outgoing interface of:
- link-local scoped packets sent by neighbor discovery
- multicast packets sent by MLD host
- multicast packets send by MLD proxy daemon that sets outgoing interface through IPV6_PKTINFO ipi6_ifindex
Link-local and multicast packets must keep their original oif after ip6_route_me_harder is called.
--- net/ipv6/netfilter.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/ipv6/netfilter.c +2 -1
@@ -25,7 +25,8 @@ int ip6_route_me_harder(struct net *net, struct sk_buff *skb)unsigned int hh_len;struct dst_entry *dst;struct flowi6 fl6 = { - .flowi6_oif = sk ? sk->sk_bound_dev_if :0 , + .flowi6_oif = sk && sk->sk_bound_dev_if ? sk->sk_bound_dev_if : +rt6_need_strict (&iph->daddr) ?skb_dst (skb)->dev->ifindex :0 , .flowi6_mark = skb->mark, .flowi6_uid =sock_net_uid (net, sk), .daddr = iph->daddr,
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 41/69 IB/mlx5: Fix page fault handling for MW
In reply to Sasha LevinFrom: Artemy Kovalyov <[email protected]>
[ Upstream commit 75b7b86bdb0df37e08e44b6c1f99010967f81944 ]
Memory windows are implemented with an indirect MKey, when a page fault event comes for a MW Mkey we need to find the MR at the end of the list of the indirect MKeys by iterating on all items from the first to the last.
The offset calculated during this process has to be zeroed after the first iteration or the next iteration will start from a wrong address, resulting incorrect ODP faulting behavior.
--- drivers/infiniband/hw/mlx5/odp.c | 1 + 1 file changed, 1 insertion(+)
drivers/infiniband/hw/mlx5/odp.c +1 -0
@@ -723,6 +723,7 @@ static int pagefault_single_data_segment(struct mlx5_ib_dev *dev, head = frame; bcnt -= frame->bcnt; + offset =0 ; }break ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 42/69 KVM: x86: fix empty-body warnings
In reply to Sasha LevinFrom: Yi Wang <[email protected]>
[ Upstream commit 354cb410d87314e2eda344feea84809e4261570a ]
We get the following warnings about empty statements when building with 'W=1':
arch/x86/kvm/lapic.c:632:53: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body] arch/x86/kvm/lapic.c:1907:42: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body] arch/x86/kvm/lapic.c:1936:65: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body] arch/x86/kvm/lapic.c:1975:44: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body]
Rework the debug helper macro to get rid of these warnings.
--- arch/x86/kvm/lapic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kvm/lapic.c +1 -1
@@ -55,7 +55,7 @@#define PRIo64 "o"/* #define apic_debug(fmt,arg...) printk(KERN_WARNING fmt,##arg) */ -#define apic_debug(fmt, arg...) +#define apic_debug(fmt, arg...) do {} while (0)/* 14 is the version for Xeon and Pentium 8.4.8*/ #define APIC_VERSION (0x14UL | ((KVM_APIC_LVT_NUM - 1) << 16))
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 43/69 x86/kvm/vmx: fix old-style function declaration
In reply to Sasha LevinFrom: Yi Wang <[email protected]>
[ Upstream commit 1e4329ee2c52692ea42cc677fb2133519718b34a ]
The inline keyword which is not at the beginning of the function declaration may trigger the following build warnings, so let's fix it:
arch/x86/kvm/vmx.c:1309:1: warning: ‘inline’ is not at beginning of declaration [-Wold-style-declaration] arch/x86/kvm/vmx.c:5947:1: warning: ‘inline’ is not at beginning of declaration [-Wold-style-declaration] arch/x86/kvm/vmx.c:5985:1: warning: ‘inline’ is not at beginning of declaration [-Wold-style-declaration] arch/x86/kvm/vmx.c:6023:1: warning: ‘inline’ is not at beginning of declaration [-Wold-style-declaration]
--- arch/x86/kvm/vmx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
arch/x86/kvm/vmx.c +4 -4
@@ -1089,7 +1089,7 @@ static void vmx_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked);static bool nested_vmx_is_page_fault_vmexit (struct vmcs12 *vmcs12,u16 error_code);static void vmx_update_msr_bitmap (struct kvm_vcpu *vcpu); -static void __always_inline vmx_disable_intercept_for_msr(unsigned long *msr_bitmap, +static __always_inline void vmx_disable_intercept_for_msr(unsigned long *msr_bitmap,u32 msr,int type); static DEFINE_PER_CPU(struct vmcs *, vmxarea);
@@ -5227,7 +5227,7 @@ static void free_vpid(int vpid)spin_unlock (&vmx_vpid_lock); } -static void __always_inline vmx_disable_intercept_for_msr(unsigned long *msr_bitmap, +static __always_inline void vmx_disable_intercept_for_msr(unsigned long *msr_bitmap,u32 msr,int type) {int f =sizeof (unsigned long );
@@ -5262,7 +5262,7 @@ static void __always_inline vmx_disable_intercept_for_msr(unsigned long *msr_bit } } -static void __always_inline vmx_enable_intercept_for_msr(unsigned long *msr_bitmap, +static __always_inline void vmx_enable_intercept_for_msr(unsigned long *msr_bitmap,u32 msr,int type) {int f =sizeof (unsigned long );
@@ -5297,7 +5297,7 @@ static void __always_inline vmx_enable_intercept_for_msr(unsigned long *msr_bitm } } -static void __always_inline vmx_set_intercept_for_msr(unsigned long *msr_bitmap, +static __always_inline void vmx_set_intercept_for_msr(unsigned long *msr_bitmap,u32 msr,int type,bool value) {if (value)
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 44/69 net: thunderx: fix NULL pointer dereference in nic_remove
In reply to Sasha LevinFrom: Lorenzo Bianconi <[email protected]>
[ Upstream commit 24a6d2dd263bc910de018c78d1148b3e33b94512 ]
Fix a possible NULL pointer dereference in nic_remove routine removing the nicpf module if nic_probe fails.
The issue can be triggered with the following reproducer:
$rmmod nicvf
$rmmod nicpf
[ 521.412008] Unable to handle kernel access to user memory outside uaccess routines at virtual address 0000000000000014 [ 521.422777] Mem abort info: [ 521.425561] ESR = 0x96000004 [ 521.428624] Exception class = DABT (current EL), IL = 32 bits [ 521.434535] SET = 0, FnV = 0 [ 521.437579] EA = 0, S1PTW = 0 [ 521.440730] Data abort info: [ 521.443603] ISV = 0, ISS = 0x00000004 [ 521.447431] CM = 0, WnR = 0 [ 521.450417] user pgtable: 4k pages, 48-bit VAs, pgdp = 0000000072a3da42 [ 521.457022] [0000000000000014] pgd=0000000000000000 [ 521.461916] Internal error: Oops: 96000004 [#1] SMP [ 521.511801] Hardware name: GIGABYTE H270-T70/MT70-HD0, BIOS T49 02/02/2018 [ 521.518664] pstate: 80400005 (Nzcv daif +PAN -UAO) [ 521.523451] pc : nic_remove+0x24/0x88 [nicpf] [ 521.527808] lr : pci_device_remove+0x48/0xd8 [ 521.532066] sp : ffff000013433cc0 [ 521.535370] x29: ffff000013433cc0 x28: ffff810f6ac50000 [ 521.540672] x27: 0000000000000000 x26: 0000000000000000 [ 521.545974] x25: 0000000056000000 x24: 0000000000000015 [ 521.551274] x23: ffff8007ff89a110 x22: ffff000001667070 [ 521.556576] x21: ffff8007ffb170b0 x20: ffff8007ffb17000 [ 521.561877] x19: 0000000000000000 x18: 0000000000000025 [ 521.567178] x17: 0000000000000000 x16: 000000000000010ffc33ff98 x8 : 0000000000000000 [ 521.593683] x7 : 0000000000000000 x6 : 0000000000000001 [ 521.598983] x5 : 0000000000000002 x4 : 0000000000000003 [ 521.604284] x3 : ffff8007ffb17184 x2 : ffff8007ffb17184 [ 521.609585] x1 : ffff000001662118 x0 : ffff000008557be0 [ 521.614887] Process rmmod (pid: 1897, stack limit = 0x00000000859535c3) [ 521.621490] Call trace: [ 521.623928] nic_remove+0x24/0x88 [nicpf] [ 521.627927] pci_device_remove+0x48/0xd8 [ 521.631847] device_release_driver_internal+0x1b0/0x248 [ 521.637062] driver_detach+0x50/0xc0 [ 521.640628] bus_remove_driver+0x60/0x100 [ 521.644627] driver_unregister+0x34/0x60 [ 521.648538] pci_unregister_driver+0x24/0xd8 [ 521.652798] nic_cleanup_module+0x14/0x111c [nicpf] [ 521.657672] __arm64_sys_delete_module+0x150/0x218 [ 521.662460] el0_svc_handler+0x94/0x110 [ 521.666287] el0_svc+0x8/0xc [ 521.669160] Code: aa1e03e0 9102c295 d503201f f9404eb3 (b9401660)
--- drivers/net/ethernet/cavium/thunder/nic_main.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/ethernet/cavium/thunder/nic_main.c +3 -0
@@ -1376,6 +1376,9 @@ static void nic_remove(struct pci_dev *pdev) {struct nicpf *nic =pci_get_drvdata (pdev); +if (!nic) +return ; +if (nic->flags &NIC_SRIOV_ENABLED )pci_disable_sriov (pdev);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 45/69 usb: gadget: u_ether: fix unsafe list iteration
In reply to Sasha LevinFrom: Marek Szyprowski <[email protected]>
[ Upstream commit c9287fa657b3328b4549c0ab39ea7f197a3d6a50 ]
list_for_each_entry_safe() is not safe for deleting entries from the list if the spin lock, which protects it, is released and reacquired during the list iteration. Fix this issue by replacing this construction with a simple check if list is empty and removing the first entry in each iteration. This is almost equivalent to a revert of the commit mentioned in the Fixes: tag.
This patch fixes following issue:
--->8---
Unable to handle kernel NULL pointer dereference at virtual address 00000104 pgd = (ptrval) [00000104] *pgd=00000000 Internal error: Oops: 817 [#1] PREEMPT SMP ARM Modules linked in: CPU: 1 PID: 84 Comm: kworker/1:1 Not tainted 4.20.0-rc2-next-20181114-00009-g8266b35ec404 #1061 Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) Workqueue: events eth_work PC is at rx_fill+0x60/0xac LR is at _raw_spin_lock_irqsave+0x50/0x5c pc : [<c065fee0>] lr : [<c0a056b8>] psr: 80000093
sp : ee7fbee8 ip : 00000100 fp : 00000000
r10: 006000c0 r9 : c10b0ab0 r8 : ee7eb5c0
r7 : ee7eb614 r6 : ee7eb5ec r5 : 000000dc r4 : ee12ac00 r3 : ee12ac24 r2 : 00000200 r1 : 60000013 r0 : ee7eb5ec
Flags: Nzcv IRQs off FIQs on Mode SVC_32 ISA ARM Segment none
Control: 10c5387d Table: 6d5dc04a DAC: 00000051 Process kworker/1:1 (pid: 84, stack limit = 0x(ptrval))
Stack: (0xee7fbee8 to 0xee7fc000)
...
[<c065fee0>] (rx_fill) from [<c0143b7c>] (process_one_work+0x200/0x738) [<c0143b7c>] (process_one_work) from [<c0144118>] (worker_thread+0x2c/0x4c8) [<c0144118>] (worker_thread) from [<c014a8a4>] (kthread+0x128/0x164) [<c014a8a4>] (kthread) from [<c01010b4>] (ret_from_fork+0x14/0x20)
Exception stack(0xee7fbfb0 to 0xee7fbff8) ... ---[ end trace 64480bc835eba7d6 ]---
--- drivers/usb/gadget/function/u_ether.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
drivers/usb/gadget/function/u_ether.c +6 -5
@@ -405,12 +405,12 @@ static int alloc_requests(struct eth_dev *dev, struct gether *link, unsigned n)static void rx_fill (struct eth_dev *dev,gfp_t gfp_flags) {struct usb_request *req; -struct usb_request *tmp;unsigned long flags;/* fill unused rxq slots with some skb */ spin_lock_irqsave (&dev->req_lock, flags); -list_for_each_entry_safe (req, tmp, &dev->rx_reqs, list) { +while (!list_empty (&dev->rx_reqs)) { + req = list_first_entry(&dev->rx_reqs, struct usb_request, list);list_del_init (&req->list);spin_unlock_irqrestore (&dev->req_lock, flags);
@@ -1125,7 +1125,6 @@ void gether_disconnect(struct gether *link) {struct eth_dev *dev = link->ioport;struct usb_request *req; -struct usb_request *tmp;WARN_ON (!dev);if (!dev)
@@ -1142,7 +1141,8 @@ void gether_disconnect(struct gether *link)*/ usb_ep_disable (link->in_ep);spin_lock (&dev->req_lock); -list_for_each_entry_safe (req, tmp, &dev->tx_reqs, list) { +while (!list_empty (&dev->tx_reqs)) { + req = list_first_entry(&dev->tx_reqs, struct usb_request, list);list_del (&req->list);spin_unlock (&dev->req_lock);
@@ -1154,7 +1154,8 @@ void gether_disconnect(struct gether *link)usb_ep_disable (link->out_ep);spin_lock (&dev->req_lock); -list_for_each_entry_safe (req, tmp, &dev->rx_reqs, list) { +while (!list_empty (&dev->rx_reqs)) { + req = list_first_entry(&dev->rx_reqs, struct usb_request, list);list_del (&req->list);spin_unlock (&dev->req_lock);
Sasha Levin
maintainerPATCH 46/69 netfilter: nf_tables: deactivate expressions in rule replecement routine
In reply to Sasha LevinFrom: Taehee Yoo <[email protected]>
[ Upstream commit ca08987885a147643817d02bf260bc4756ce8cd4 ]
There is no expression deactivation call from the rule replacement path, hence, chain counter is not decremented. A few steps to reproduce the problem:
%nft add table ip filter
%nft add chain ip filter c1
%nft add chain ip filter c1
%nft add rule ip filter c1 jump c2
%nft replace rule ip filter c1 handle 3 accept
%nft flush ruleset
<jump c2> expression means immediate NFT_JUMP to chain c2. Reference count of chain c2 is increased when the rule is added.
When rule is deleted or replaced, the reference counter of c2 should be decreased via nft_rule_expr_deactivate() which calls nft_immediate_deactivate().
Splat looks like:
[ 214.396453] WARNING: CPU: 1 PID: 21 at net/netfilter/nf_tables_api.c:1432 nf_tables_chain_destroy.isra.38+0x2f9/0x3a0 [nf_tables] [ 214.398983] Modules linked in: nf_tables nfnetlink [ 214.398983] CPU: 1 PID: 21 Comm: kworker/1:1 Not tainted 4.20.0-rc2+ #44 [ 214.398983] Workqueue: events nf_tables_trans_destroy_work [nf_tables] [ 214.398983] RIP: 0010:nf_tables_chain_destroy.isra.38+0x2f9/0x3a0 [nf_tables] [ 214.398983] Code: 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 80 3c 02 00 0f 85 8e 00 00 00 48 8b 7b 58 e8 e1 2c 4e c6 48 89 df e8 d9 2c 4e c6 eb 9a <0f> 0b eb 96 0f 0b e9 7e fe ff ff e8 a7 7e 4e c6 e9 a4 fe ff ff e8 [ 214.398983] RSP: 0018:ffff8881152874e8 EFLAGS: 00010202 [ 214.398983] RAX: 0000000000000001 RBX: ffff88810ef9fc28 RCX: ffff8881152876f0 [ 214.398983] RDX: dffffc0000000000 RSI: 1ffff11022a50ede RDI: ffff88810ef9fc78 [ 214.398983] RBP: 1ffff11022a50e9d R08: 0000000080000000 R09: 0000000000000000 [ 214.398983] R10: 0000000000000000 R11: 0000000000000000 R12: 1ffff11022a50eba [ 214.398983] R13: ffff888114446e08 R14: ffff8881152876f0 R15: ffffed1022a50ed6 [ 214.398983] FS: 0000000000000000(0000) GS:ffff888116400000(0000) knlGS:0000000000000000 [ 214.398983] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 214.398983] CR2: 00007fab9bb5f868 CR3: 000000012aa16000 CR4: 00000000001006e0 [ 214.398983] Call Trace: [ 214.398983] ? nf_tables_table_destroy.isra.37+0x100/0x100 [nf_tables] [ 214.398983] ? __kasan_slab_free+0x145/0x180 [ 214.398983] ? nf_tables_trans_destroy_work+0x439/0x830 [nf_tables] [ 214.398983] ? kfree+0xdb/0x280 [ 214.398983] nf_tables_trans_destroy_work+0x5f5/0x830 [nf_tables]
[ ... ]
Reported by: Christoph Anton Mitterer <[email protected]>
--- net/netfilter/nf_tables_api.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-)
net/netfilter/nf_tables_api.c +4 -11
@@ -2400,21 +2400,14 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk, }if (nlh->nlmsg_flags &NLM_F_REPLACE ) { -if (!nft_is_active_next (net, old_rule)) { - err = -ENOENT ; - goto err2; - } - trans =nft_trans_rule_add (&ctx,NFT_MSG_DELRULE , - old_rule); + trans =nft_trans_rule_add (&ctx,NFT_MSG_NEWRULE , rule);if (trans ==NULL ) { err = -ENOMEM ; goto err2; } -nft_deactivate_next (net, old_rule); - chain->use--; - -if (nft_trans_rule_add (&ctx,NFT_MSG_NEWRULE , rule) ==NULL ) { - err = -ENOMEM ; + err =nft_delrule (&ctx, old_rule); +if (err <0 ) { +nft_trans_destroy (trans); goto err2; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 47/69 cachefiles: Fix page leak in cachefiles_read_backing_file while vmscan is active
In reply to Sasha LevinFrom: Kiran Kumar Modukuri <[email protected]>
[ Upstream commit 9a24ce5b66f9c8190d63b15f4473600db4935f1f ]
[Description]
In a heavily loaded system where the system pagecache is nearing memory limits and fscache is enabled, pages can be leaked by fscache while trying read pages from cachefiles backend. This can happen because two applications can be reading same page from a single mount, two threads can be trying to read the backing page at same time. This results in one of the threads finding that a page for the backing file or netfs file is already in the radix tree. During the error handling cachefiles does not clean up the reference on backing page, leading to page leak.
[Fix]
The fix is straightforward, to decrement the reference when error is encountered.
[dhowells: Note that I've removed the clearance and put of newpage as
they aren't attested in the commit message and don't appear to actually achieve anything since a new page is only allocated is newpage!=NULL and any residual new page is cleared before returning.]
[Testing]
I have tested the fix using following method for 12+ hrs.
1) mkdir -p /mnt/nfs ; mount -o vers=3,fsc <server_ip>:/export /mnt/nfs
2) create 10000 files of 2.8MB in a NFS mount.
3) start a thread to simulate heavy VM presssure
(while true ; do echo 3 > /proc/sys/vm/drop_caches ; sleep 1 ; done)&
4) start multiple parallel reader for data set at same time
find /mnt/nfs -type f | xargs -P 80 cat > /dev/null & find /mnt/nfs -type f | xargs -P 80 cat > /dev/null & find /mnt/nfs -type f | xargs -P 80 cat > /dev/null &
..
..
find /mnt/nfs -type f | xargs -P 80 cat > /dev/null & find /mnt/nfs -type f | xargs -P 80 cat > /dev/null &
5) finally check using cat /proc/fs/fscache/stats | grep -i pages ; free -h , cat /proc/meminfo and page-types -r -b lru to ensure all pages are freed.
--- fs/cachefiles/rdwr.c | 6 ++++++ 1 file changed, 6 insertions(+)
fs/cachefiles/rdwr.c +6 -0
@@ -537,7 +537,10 @@ static int cachefiles_read_backing_file(struct cachefiles_object *object, netpage->index, cachefiles_gfp);if (ret <0 ) {if (ret == -EEXIST ) { +put_page (backpage); + backpage =NULL ;put_page (netpage); + netpage =NULL ;fscache_retrieval_complete (op,1 );continue ; }
@@ -610,7 +613,10 @@ static int cachefiles_read_backing_file(struct cachefiles_object *object, netpage->index, cachefiles_gfp);if (ret <0 ) {if (ret == -EEXIST ) { +put_page (backpage); + backpage =NULL ;put_page (netpage); + netpage =NULL ;fscache_retrieval_complete (op,1 );continue ; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 48/69 igb: fix uninitialized variables
In reply to Sasha LevinFrom: Yunjian Wang <[email protected]>
[ Upstream commit e4c39f7926b4de355f7df75651d75003806aae09 ]
This patch fixes the variable 'phy_word' may be used uninitialized.
--- drivers/net/ethernet/intel/igb/e1000_i210.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/intel/igb/e1000_i210.c +1 -0
@@ -862,6 +862,7 @@ s32 igb_pll_workaround_i210(struct e1000_hw *hw) nvm_word =E1000_INVM_DEFAULT_AL ; tmp_nvm = nvm_word |E1000_INVM_PLL_WO_VAL ;igb_write_phy_reg_82580 (hw,I347AT4_PAGE_SELECT ,E1000_PHY_PLL_FREQ_PAGE ); + phy_word =E1000_PHY_PLL_UNCONF ;for (i =0 ; i <E1000_MAX_PLL_TRIES ; i++) {/* check current state directly from internal PHY */ igb_read_phy_reg_82580 (hw,E1000_PHY_PLL_FREQ_REG , &phy_word);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 49/69 ixgbe: recognize 1000BaseLX SFP modules as 1Gbps
In reply to Sasha LevinFrom: Josh Elsasser <[email protected]>
[ Upstream commit a8bf879af7b1999eba36303ce9cc60e0e7dd816c ]
Add the two 1000BaseLX enum values to the X550's check for 1Gbps modules, allowing the core driver code to establish a link over this SFP type.
This is done by the out-of-tree driver but the fix wasn't in mainline.
--- drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c +3 -1
@@ -2257,7 +2257,9 @@ static s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw, *autoneg = false;if (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || - hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1) { + hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1) { *speed =IXGBE_LINK_SPEED_1GB_FULL ;return 0 ; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 50/69 rapidio/rionet: do not free skb before reading its length
In reply to Sasha LevinFrom: Pan Bian <[email protected]>
[ Upstream commit cfc435198f53a6fa1f656d98466b24967ff457d0 ]
skb is freed via dev_kfree_skb_any, however, skb->len is read then. This may result in a use-after-free bug.
--- drivers/net/rionet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/rionet.c +1 -1
@@ -216,9 +216,9 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)* it just report sending a packet to the target * (without actual packet transfer). */ -dev_kfree_skb_any (skb); ndev->stats.tx_packets++; ndev->stats.tx_bytes += skb->len; +dev_kfree_skb_any (skb); } }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 51/69 net: hisilicon: remove unexpected free_netdev
In reply to Sasha LevinFrom: Pan Bian <[email protected]>
[ Upstream commit c758940158bf29fe14e9d0f89d5848f227b48134 ]
The net device ndev is freed via free_netdev when failing to register the device. The control flow then jumps to the error handling code block. ndev is used and freed again. Resulting in a use-after-free bug.
--- drivers/net/ethernet/hisilicon/hip04_eth.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/net/ethernet/hisilicon/hip04_eth.c +1 -3
@@ -914,10 +914,8 @@ static int hip04_mac_probe(struct platform_device *pdev) } ret =register_netdev (ndev); -if (ret) { -free_netdev (ndev); +if (ret) goto alloc_fail; - }return 0 ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 52/69 s390/qeth: fix length check in SNMP processing
In reply to Sasha LevinFrom: Julian Wiedmann <[email protected]>
[ Upstream commit 9a764c1e59684c0358e16ccaafd870629f2cfe67 ]
The response for a SNMP request can consist of multiple parts, which the cmd callback stages into a kernel buffer until all parts have been received. If the callback detects that the staging buffer provides insufficient space, it bails out with error.
This processing is buggy for the first part of the response - while it initially checks for a length of 'data_len', it later copies an additional amount of 'offsetof(struct qeth_snmp_cmd, data)' bytes.
Fix the calculation of 'data_len' for the first part of the response. This also nicely cleans up the memcpy code.
--- drivers/s390/net/qeth_core_main.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-)
drivers/s390/net/qeth_core_main.c +12 -15
@@ -4545,8 +4545,8 @@ static int qeth_snmp_command_cb(struct qeth_card *card, {struct qeth_ipa_cmd *cmd;struct qeth_arp_query_info *qinfo; -struct qeth_snmp_cmd *snmp;unsigned char *data; +void *snmp_data;__u16 data_len;QETH_CARD_TEXT (card,3 ,"snpcmdcb" );
@@ -4554,7 +4554,6 @@ static int qeth_snmp_command_cb(struct qeth_card *card, cmd = (struct qeth_ipa_cmd *) sdata; data = (unsigned char *)((char *)cmd - reply->offset); qinfo = (struct qeth_arp_query_info *) reply->param; - snmp = &cmd->data.setadapterparms.data.snmp;if (cmd->hdr.return_code) {QETH_CARD_TEXT_ (card,4 ,"scer1%x" , cmd->hdr.return_code);
@@ -4567,10 +4566,15 @@ static int qeth_snmp_command_cb(struct qeth_card *card,return 0 ; } data_len = *((__u16 *)QETH_IPA_PDU_LEN_PDU1 (data)); -if (cmd->data.setadapterparms.hdr.seq_no ==1 ) - data_len -= (__u16)((char *)&snmp->data - (char *)cmd); -else - data_len -= (__u16)((char *)&snmp->request - (char *)cmd); +if (cmd->data.setadapterparms.hdr.seq_no ==1 ) { + snmp_data = &cmd->data.setadapterparms.data.snmp; + data_len -= offsetof(struct qeth_ipa_cmd , + data.setadapterparms.data.snmp); + }else { + snmp_data = &cmd->data.setadapterparms.data.snmp.request; + data_len -= offsetof(struct qeth_ipa_cmd , + data.setadapterparms.data.snmp.request); + }/* check if there is enough room in userspace */ if ((qinfo->udata_len - qinfo->udata_offset) < data_len) {
@@ -4583,16 +4587,9 @@ static int qeth_snmp_command_cb(struct qeth_card *card,QETH_CARD_TEXT_ (card,4 ,"sseqn%i" , cmd->data.setadapterparms.hdr.seq_no);/*copy entries to user buffer*/ -if (cmd->data.setadapterparms.hdr.seq_no ==1 ) { -memcpy (qinfo->udata + qinfo->udata_offset, - (char *)snmp, - data_len + offsetof(struct qeth_snmp_cmd , data)); - qinfo->udata_offset += offsetof(struct qeth_snmp_cmd , data); - }else { -memcpy (qinfo->udata + qinfo->udata_offset, - (char *)&snmp->request, data_len); - } +memcpy (qinfo->udata + qinfo->udata_offset, snmp_data, data_len); qinfo->udata_offset += data_len; +/* check if all replies received ... */ QETH_CARD_TEXT_ (card,4 ,"srtot%i" , cmd->data.setadapterparms.hdr.used_total);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 53/69 drm/amdgpu: Add delay after enable RLC ucode
In reply to Sasha LevinFrom: shaoyunl <[email protected]>
[ Upstream commit ad97d9de45835b6a0f71983b0ae0cffd7306730a ]
Driver shouldn't try to access any GFX registers until RLC is idle. During the test, it took 12 seconds for RLC to clear the BUSY bit in RLC_GPM_STAT register which is un-acceptable for driver. As per RLC engineer, it would take RLC Ucode less than 10,000 GFXCLK cycles to finish its critical section. In a lowest 300M enginer clock setting(default from vbios), 50 us delay is enough.
This commit fix the hang when RLC introduce the work around for XGMI which requires more cycles to setup more registers than normal
--- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +4 -3
@@ -1992,12 +1992,13 @@ static void gfx_v9_0_rlc_start(struct amdgpu_device *adev)#endif WREG32_FIELD15 (GC ,0 ,RLC_CNTL ,RLC_ENABLE_F32 ,1 ); +udelay (50 );/* carrizo do enable cp interrupt after cp inited */ -if (!(adev->flags &AMD_IS_APU )) +if (!(adev->flags &AMD_IS_APU )) {gfx_v9_0_enable_gui_idle_interrupt (adev, true); - -udelay (50 ); +udelay (50 ); + }#ifdef AMDGPU_RLC_DEBUG_RETRY /* RLC_GPM_GENERAL_6 : RLC Ucode version */
Signature · 6 lines
2.17.1 _______________________________________________ amd-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Sasha Levin
maintainerPATCH 54/69 drm/ast: fixed reading monitor EDID not stable issue
In reply to Sasha LevinFrom: "Y.C. Chen" <[email protected]>
[ Upstream commit 300625620314194d9e6d4f6dda71f2dc9cf62d9f ]
v1: over-sample data to increase the stability with some specific monitors
v2: refine to avoid infinite loop
v3: remove un-necessary "volatile" declaration
[airlied: fix two checkpatch warnings]
--- drivers/gpu/drm/ast/ast_mode.c | 36 ++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-)
drivers/gpu/drm/ast/ast_mode.c +30 -6
@@ -973,9 +973,21 @@ static int get_clock(void *i2c_priv) {struct ast_i2c_chan *i2c = i2c_priv;struct ast_private *ast = i2c->dev->dev_private; -uint32_t val; +uint32_t val, val2, count, pass; + + count =0 ; + pass =0 ; + val = (ast_get_index_reg_mask (ast,AST_IO_CRTC_PORT ,0xb7 ,0x10 ) >>4 ) &0x01 ; +do { + val2 = (ast_get_index_reg_mask (ast,AST_IO_CRTC_PORT ,0xb7 ,0x10 ) >>4 ) &0x01 ; +if (val == val2) { + pass++; + }else { + pass =0 ; + val = (ast_get_index_reg_mask (ast,AST_IO_CRTC_PORT ,0xb7 ,0x10 ) >>4 ) &0x01 ; + } + }while ((pass <5 ) && (count++ <0x10000 )); - val =ast_get_index_reg_mask (ast,AST_IO_CRTC_PORT ,0xb7 ,0x10 ) >>4 ;return val &1 ?1 :0 ; }
@@ -983,9 +995,21 @@ static int get_data(void *i2c_priv) {struct ast_i2c_chan *i2c = i2c_priv;struct ast_private *ast = i2c->dev->dev_private; -uint32_t val; +uint32_t val, val2, count, pass; + + count =0 ; + pass =0 ; + val = (ast_get_index_reg_mask (ast,AST_IO_CRTC_PORT ,0xb7 ,0x20 ) >>5 ) &0x01 ; +do { + val2 = (ast_get_index_reg_mask (ast,AST_IO_CRTC_PORT ,0xb7 ,0x20 ) >>5 ) &0x01 ; +if (val == val2) { + pass++; + }else { + pass =0 ; + val = (ast_get_index_reg_mask (ast,AST_IO_CRTC_PORT ,0xb7 ,0x20 ) >>5 ) &0x01 ; + } + }while ((pass <5 ) && (count++ <0x10000 )); - val =ast_get_index_reg_mask (ast,AST_IO_CRTC_PORT ,0xb7 ,0x20 ) >>5 ;return val &1 ?1 :0 ; }
@@ -998,7 +1022,7 @@ static void set_clock(void *i2c_priv, int clock)for (i =0 ; i <0x10000 ; i++) { ujcrb7 = ((clock &0x01 ) ?0 :1 ); -ast_set_index_reg_mask (ast,AST_IO_CRTC_PORT ,0xb7 ,0xfe , ujcrb7); +ast_set_index_reg_mask (ast,AST_IO_CRTC_PORT ,0xb7 ,0xf4 , ujcrb7); jtemp =ast_get_index_reg_mask (ast,AST_IO_CRTC_PORT ,0xb7 ,0x01 );if (ujcrb7 == jtemp)break ;
@@ -1014,7 +1038,7 @@ static void set_data(void *i2c_priv, int data)for (i =0 ; i <0x10000 ; i++) { ujcrb7 = ((data &0x01 ) ?0 :1 ) <<2 ; -ast_set_index_reg_mask (ast,AST_IO_CRTC_PORT ,0xb7 ,0xfb , ujcrb7); +ast_set_index_reg_mask (ast,AST_IO_CRTC_PORT ,0xb7 ,0xf1 , ujcrb7); jtemp =ast_get_index_reg_mask (ast,AST_IO_CRTC_PORT ,0xb7 ,0x04 );if (ujcrb7 == jtemp)break ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 55/69 xen: xlate_mmu: add missing header to fix 'W=1' warning
In reply to Sasha LevinFrom: Srikanth Boddepalli <[email protected]>
[ Upstream commit 72791ac854fea36034fa7976b748fde585008e78 ]
Add a missing header otherwise compiler warns about missed prototype:
drivers/xen/xlate_mmu.c:183:5: warning: no previous prototype for 'xen_xlate_unmap_gfn_range?' [-Wmissing-prototypes]
int xen_xlate_unmap_gfn_range(struct vm_area_struct *vma,
^~~~~~~~~~~~~~~~~~~~~~~~~
--- drivers/xen/xlate_mmu.c | 1 + 1 file changed, 1 insertion(+)
drivers/xen/xlate_mmu.c +1 -0
@@ -36,6 +36,7 @@#include <asm/xen/hypervisor.h> #include <xen/xen.h> +#include <xen/xen-ops.h> #include <xen/page.h> #include <xen/interface/xen.h> #include <xen/interface/memory.h>
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 56/69 Revert "xen/balloon: Mark unallocated host memory as UNUSABLE"
In reply to Sasha LevinFrom: Igor Druzhinin <[email protected]>
[ Upstream commit 123664101aa2156d05251704fc63f9bcbf77741a ]
This reverts commit b3cf8528bb21febb650a7ecbf080d0647be40b9f.
That commit unintentionally broke Xen balloon memory hotplug with "hotplug_unpopulated" set to 1. As long as "System RAM" resource got assigned under a new "Unusable memory" resource in IO/Mem tree any attempt to online this memory would fail due to general kernel restrictions on having "System RAM" resources as 1st level only.
The original issue that commit has tried to workaround fa564ad96366 ("x86/PCI: Enable a 64bit BAR on AMD Family 15h (Models 00-1f, 30-3f, 60-7f)") also got amended by the following 03a551734 ("x86/PCI: Move and shrink AMD 64-bit window to avoid conflict") which made the original fix to Xen ballooning unnecessary.
--- arch/x86/xen/enlighten.c | 78 ---------------------------------------- arch/x86/xen/setup.c | 6 ++-- drivers/xen/balloon.c | 65 +++++---------------------------- include/xen/balloon.h | 5 --- 4 files changed, 13 insertions(+), 141 deletions(-)
arch/x86/xen/enlighten.c +0 -78
@@ -7,7 +7,6 @@#include <xen/features.h> #include <xen/page.h> -#include <xen/interface/memory.h> #include <asm/xen/hypercall.h> #include <asm/xen/hypervisor.h>
@@ -336,80 +335,3 @@ void xen_arch_unregister_cpu(int num) }EXPORT_SYMBOL (xen_arch_unregister_cpu);#endif - -#ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG -void __init arch_xen_balloon_init (struct resource *hostmem_resource) -{ -struct xen_memory_map memmap; -int rc; -unsigned int i, last_guest_ram; -phys_addr_t max_addr =PFN_PHYS (max_pfn); -struct e820_table *xen_e820_table; -const struct e820_entry *entry; -struct resource *res; - -if (!xen_initial_domain ()) -return ; - - xen_e820_table =kmalloc (sizeof (*xen_e820_table),GFP_KERNEL ); -if (!xen_e820_table) -return ; - - memmap.nr_entries =ARRAY_SIZE (xen_e820_table->entries); -set_xen_guest_handle (memmap.buffer, xen_e820_table->entries); - rc =HYPERVISOR_memory_op (XENMEM_machine_memory_map, &memmap); -if (rc) { -pr_warn ("%s: Can't read host e820 (%d)\n" , __func__, rc); - goto out; - } - - last_guest_ram =0 ; -for (i =0 ; i < memmap.nr_entries; i++) { -if (xen_e820_table->entries[i].addr >= max_addr) -break ; -if (xen_e820_table->entries[i].type ==E820_TYPE_RAM ) - last_guest_ram = i; - } - - entry = &xen_e820_table->entries[last_guest_ram]; -if (max_addr >= entry->addr + entry->size) - goto out;/* No unallocated host RAM. */ - - hostmem_resource->start = max_addr; - hostmem_resource->end = entry->addr + entry->size; - -/* -* Mark non-RAM regions between the end of dom0 RAM and end of host RAM -* as unavailable. The rest of that region can be used for hotplug-based -* ballooning. -*/ -for (; i < memmap.nr_entries; i++) { - entry = &xen_e820_table->entries[i]; - -if (entry->type ==E820_TYPE_RAM ) -continue ; - -if (entry->addr >= hostmem_resource->end) -break ; - - res =kzalloc (sizeof (*res),GFP_KERNEL ); -if (!res) - goto out; - - res->name ="Unavailable host RAM" ; - res->start = entry->addr; - res->end = (entry->addr + entry->size < hostmem_resource->end) ? - entry->addr + entry->size : hostmem_resource->end; - rc =insert_resource (hostmem_resource, res); -if (rc) { -pr_warn ("%s: Can't insert [%llx - %llx) (%d)\n" , - __func__, res->start, res->end, rc); -kfree (res); - goto out; - } - } - - out: -kfree (xen_e820_table); -} -#endif /* CONFIG_XEN_BALLOON_MEMORY_HOTPLUG */
arch/x86/xen/setup.c +4 -2
@@ -808,6 +808,7 @@ char * __init xen_memory_setup(void) addr = xen_e820_table.entries[0 ].addr; size = xen_e820_table.entries[0 ].size;while (i < xen_e820_table.nr_entries) { +bool discard = false; chunk_size = size; type = xen_e820_table.entries[i].type;
@@ -823,10 +824,11 @@ char * __init xen_memory_setup(void)xen_add_extra_mem (pfn_s, n_pfns); xen_max_p2m_pfn = pfn_s + n_pfns; }else - type =E820_TYPE_UNUSABLE ; + discard = true; } -xen_align_and_add_e820_region (addr, chunk_size, type); +if (!discard) +xen_align_and_add_e820_region (addr, chunk_size, type); addr += chunk_size; size -= chunk_size;
drivers/xen/balloon.c +9 -56
91 lines not on this page · raw message
include/xen/balloon.h +0 -5
@@ -44,8 +44,3 @@ static inline void xen_balloon_init(void) { }#endif - -#ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG -struct resource ; -void arch_xen_balloon_init (struct resource *hostmem_resource); -#endif
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 57/69 pstore/ram: Correctly calculate usable PRZ bytes
In reply to Sasha LevinFrom: Kees Cook <[email protected]>
[ Upstream commit 89d328f637b9904b6d4c9af73c8a608b8dd4d6f8 ]
The actual number of bytes stored in a PRZ is smaller than the bytes requested by platform data, since there is a header on each PRZ. Additionally, if ECC is enabled, there are trailing bytes used as well. Normally this mismatch doesn't matter since PRZs are circular buffers and the leading "overflow" bytes are just thrown away. However, in the case of a compressed record, this rather badly corrupts the results.
This corruption was visible with "ramoops.mem_size=204800 ramoops.ecc=1". Any stored crashes would not be uncompressable (producing a pstorefs "dmesg-*.enc.z" file), and triggering errors at boot:
[ 2.790759] pstore: crypto_comp_decompress failed, ret = -22!
Backporting this depends on commit 70ad35db3321 ("pstore: Convert console write to use ->write_buf")
--- fs/pstore/ram.c | 15 ++++++--------- include/linux/pstore.h | 5 ++++- 2 files changed, 10 insertions(+), 10 deletions(-)
fs/pstore/ram.c +6 -9
@@ -804,17 +804,14 @@ static int ramoops_probe(struct platform_device *pdev) cxt->pstore.data = cxt;/* -* Console can handle any buffer size, so prefer LOG_LINE_MAX. If we -* have to handle dumps, we must have at least record_size buffer. And -* for ftrace, bufsize is irrelevant (if bufsize is 0, buf will be -* ZERO_SIZE_PTR). +* Since bufsize is only used for dmesg crash dumps, it +* must match the size of the dprz record (after PRZ header +* and ECC bytes have been accounted for). */ -if (cxt->console_size) - cxt->pstore.bufsize =1024 ;/* LOG_LINE_MAX */ - cxt->pstore.bufsize =max (cxt->record_size, cxt->pstore.bufsize); - cxt->pstore.buf =kmalloc (cxt->pstore.bufsize,GFP_KERNEL ); + cxt->pstore.bufsize = cxt->dprzs[0 ]->buffer_size; + cxt->pstore.buf =kzalloc (cxt->pstore.bufsize,GFP_KERNEL );if (!cxt->pstore.buf) { -pr_err ("cannot allocate pstore buffer\n" ); +pr_err ("cannot allocate pstore crash dump buffer\n" ); err = -ENOMEM ; goto fail_clear; }
include/linux/pstore.h +4 -1
@@ -90,7 +90,10 @@ struct pstore_record {* * @buf_lock: spinlock to serialize access to @buf * @buf: preallocated crash dump buffer -* @bufsize: size of @buf available for crash dump writes +* @bufsize: size of @buf available for crash dump bytes (must match +* smallest number of bytes available for writing to a +* backend entry, since compressed bytes don't take kindly +* to being truncated) * * @read_mutex: serializes @open, @read, @close, and @erase callbacks * @flags: bitfield of frontends the backend can accept writes for
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 58/69 fscache: fix race between enablement and dropping of object
In reply to Sasha LevinFrom: NeilBrown <[email protected]>
[ Upstream commit c5a94f434c82529afda290df3235e4d85873c5b4 ]
It was observed that a process blocked indefintely in __fscache_read_or_alloc_page(), waiting for FSCACHE_COOKIE_LOOKING_UP to be cleared via fscache_wait_for_deferred_lookup().
At this time, ->backing_objects was empty, which would normaly prevent __fscache_read_or_alloc_page() from getting to the point of waiting. This implies that ->backing_objects was cleared *after* __fscache_read_or_alloc_page was was entered.
When an object is "killed" and then "dropped", FSCACHE_COOKIE_LOOKING_UP is cleared in fscache_lookup_failure(), then KILL_OBJECT and DROP_OBJECT are "called" and only in DROP_OBJECT is ->backing_objects cleared. This leaves a window where something else can set FSCACHE_COOKIE_LOOKING_UP and __fscache_read_or_alloc_page() can start waiting, before ->backing_objects is cleared
There is some uncertainty in this analysis, but it seems to be fit the observations. Adding the wake in this patch will be handled correctly by __fscache_read_or_alloc_page(), as it checks if ->backing_objects is empty again, after waiting.
Customer which reported the hang, also report that the hang cannot be reproduced with this fix.
The backtrace for the blocked process looked like:
PID: 29360 TASK: ffff881ff2ac0f80 CPU: 3 COMMAND: "zsh"
#0 [ffff881ff43efbf8] schedule at ffffffff815e56f1
#1 [ffff881ff43efc58] bit_wait at ffffffff815e64ed
#2 [ffff881ff43efc68] __wait_on_bit at ffffffff815e61b8
#3 [ffff881ff43efca0] out_of_line_wait_on_bit at ffffffff815e625e
#4 [ffff881ff43efd08] fscache_wait_for_deferred_lookup at ffffffffa04f2e8f [fscache] #5 [ffff881ff43efd18] __fscache_read_or_alloc_page at ffffffffa04f2ffe [fscache] #6 [ffff881ff43efd58] __nfs_readpage_from_fscache at ffffffffa0679668 [nfs] #7 [ffff881ff43efd78] nfs_readpage at ffffffffa067092b [nfs]
#8 [ffff881ff43efda0] generic_file_read_iter at ffffffff81187a73
#9 [ffff881ff43efe50] nfs_file_read at ffffffffa066544b [nfs]
#10 [ffff881ff43efe70] __vfs_read at ffffffff811fc756
#11 [ffff881ff43efee8] vfs_read at ffffffff811fccfa
#12 [ffff881ff43eff18] sys_read at ffffffff811fda62
#13 [ffff881ff43eff50] entry_SYSCALL_64_fastpath at ffffffff815e986e
--- fs/fscache/object.c | 3 +++ 1 file changed, 3 insertions(+)
fs/fscache/object.c +3 -0
@@ -715,6 +715,9 @@ static const struct fscache_state *fscache_drop_object(struct fscache_object *obif (awaken)wake_up_bit (&cookie->flags,FSCACHE_COOKIE_INVALIDATING ); +if (test_and_clear_bit (FSCACHE_COOKIE_LOOKING_UP , &cookie->flags)) +wake_up_bit (&cookie->flags,FSCACHE_COOKIE_LOOKING_UP ); +/* Prevent a race with our last child, which has to signal EV_CLEARED * before dropping our spinlock.
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 59/69 fscache, cachefiles: remove redundant variable 'cache'
In reply to Sasha LevinFrom: Colin Ian King <[email protected]>
[ Upstream commit 31ffa563833576bd49a8bf53120568312755e6e2 ]
Variable 'cache' is being assigned but is never used hence it is redundant and can be removed.
Cleans up clang warning:
warning: variable 'cache' set but not used [-Wunused-but-set-variable]
--- fs/cachefiles/rdwr.c | 3 --- 1 file changed, 3 deletions(-)
fs/cachefiles/rdwr.c +0 -3
@@ -969,11 +969,8 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page)void cachefiles_uncache_page (struct fscache_object *_object,struct page *page) {struct cachefiles_object *object; -struct cachefiles_cache *cache; object = container_of(_object, struct cachefiles_object, fscache); - cache =container_of (object->fscache.cache, - struct cachefiles_cache, cache);_enter ("%p,{%lu}" , object, page->index);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 60/69 nvme: flush namespace scanning work just before removing namespaces
In reply to Sasha LevinFrom: Sagi Grimberg <[email protected]>
[ Upstream commit f6c8e432cb0479255322c5d0335b9f1699a0270c ]
nvme_stop_ctrl can be called also for reset flow and there is no need to flush the scan_work as namespaces are not being removed. This can cause deadlock in rdma, fc and loop drivers since nvme_stop_ctrl barriers before controller teardown (and specifically I/O cancellation of the scan_work itself) takes place, but the scan_work will be blocked anyways so there is no need to flush it.
Instead, move scan_work flush to nvme_remove_namespaces() where it really needs to flush.
Reported-by: Ming Lei <ming.lei at redhat.com>
Signed-off-by: Sagi Grimberg <sagi at grimberg.me>
Reviewed-by: Keith Busch <keith.busch at intel.com> Reviewed by: James Smart <jsmart2021 at gmail.com>
Tested-by: Ewan D. Milne <emilne at redhat.com>
Signed-off-by: Christoph Hellwig <hch at lst.de>
Signed-off-by: Sasha Levin <sashal at kernel.org>
--- drivers/nvme/host/core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/nvme/host/core.c +3 -1
@@ -2572,6 +2572,9 @@ void nvme_remove_namespaces(struct nvme_ctrl *ctrl) {struct nvme_ns *ns, *next; +/* prevent racing with ns scanning */ +flush_work (&ctrl->scan_work); +/* * The dead states indicates the controller was not gracefully * disconnected. In that case, we won't be able to flush any data while
@@ -2743,7 +2746,6 @@ void nvme_stop_ctrl(struct nvme_ctrl *ctrl) {nvme_stop_keep_alive (ctrl);flush_work (&ctrl->async_event_work); -flush_work (&ctrl->scan_work);cancel_work_sync (&ctrl->fw_act_work); }EXPORT_SYMBOL_GPL (nvme_stop_ctrl);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 61/69 ACPI/IORT: Fix iort_get_platform_device_domain() uninitialized pointer value
In reply to Sasha LevinFrom: Lorenzo Pieralisi <[email protected]>
[ Upstream commit ea2412dc21cc790335d319181dddc43682aef164 ]
Running the Clang static analyzer on IORT code detected the following error:
Logic error: Branch condition evaluates to a garbage value
in
iort_get_platform_device_domain()
If the named component associated with a given device has no IORT mappings, iort_get_platform_device_domain() exits its MSI mapping loop with msi_parent pointer containing garbage, which can lead to erroneous code path execution.
Initialize the msi_parent pointer, fixing the bug.
platform device")
--- drivers/acpi/arm64/iort.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/acpi/arm64/iort.c +1 -1
@@ -547,7 +547,7 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)*/ static struct irq_domain *iort_get_platform_device_domain (struct device *dev) { -struct acpi_iort_node *node, *msi_parent; +struct acpi_iort_node *node, *msi_parent =NULL ;struct fwnode_handle *iort_fwnode;struct acpi_iort_its_group *its;int i;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 62/69 test_hexdump: use memcpy instead of strncpy
In reply to Sasha LevinFrom: Linus Torvalds <[email protected]>
[ Upstream commit b1286ed7158e9b62787508066283ab0b8850b518 ]
New versions of gcc reasonably warn about the odd pattern of
strncpy(p, q, strlen(q));
which really doesn't make sense: the strncpy() ends up being just a slow and odd way to write memcpy() in this case.
Apparently there was a patch for this floating around earlier, but it got lost.
--- lib/test_hexdump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
lib/test_hexdump.c +1 -1
@@ -81,7 +81,7 @@ static void __init test_hexdump_prepare_test(size_t len, int rowsize,const char *q = *result++;size_t amount =strlen (q); -strncpy (p, q, amount); +memcpy (p, q, amount); p += amount; *p++ =' ' ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 63/69 unifdef: use memcpy instead of strncpy
In reply to Sasha LevinFrom: Linus Torvalds <[email protected]>
[ Upstream commit 38c7b224ce22c25fed04007839edf974bd13439d ]
New versions of gcc reasonably warn about the odd pattern of
strncpy(p, q, strlen(q));
which really doesn't make sense: the strncpy() ends up being just a slow and odd way to write memcpy() in this case.
There was a comment about _why_ the code used strncpy - to avoid the terminating NUL byte, but memcpy does the same and avoids the warning.
--- scripts/unifdef.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
scripts/unifdef.c +2 -2
@@ -395,7 +395,7 @@ usage(void)* When we have processed a group that starts off with a known-false * #if/#elif sequence (which has therefore been deleted) followed by a * #elif that we don't understand and therefore must keep, we edit the -* latter into a #if to keep the nesting correct. We use strncpy() to +* latter into a #if to keep the nesting correct. We use memcpy() to * overwrite the 4 byte token "elif" with "if " without a '\0' byte. * * When we find a true #elif in a group, the following block will
@@ -450,7 +450,7 @@ static void Idrop (void) { Fdrop(); ignoreon(); }static void Itrue (void ) {Ftrue ();ignoreon (); }static void Ifalse (void ) {Ffalse ();ignoreon (); }/* modify this line */ -static void Mpass (void ) {strncpy (keyword,"if " ,4 );Pelif (); } +static void Mpass (void ) {memcpy (keyword,"if " ,4 );Pelif (); }static void Mtrue (void ) {keywordedit ("else" );state (IS_TRUE_MIDDLE ); }static void Melif (void ) {keywordedit ("endif" );state (IS_FALSE_TRAILER ); }static void Melse (void ) {keywordedit ("endif" );state (IS_FALSE_ELSE ); }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 64/69 ocfs2: fix deadlock caused by ocfs2_defrag_extent()
In reply to Sasha LevinFrom: Larry Chen <[email protected]>
[ Upstream commit e21e57445a64598b29a6f629688f9b9a39e7242a ]
ocfs2_defrag_extent may fall into deadlock.
ocfs2_ioctl_move_extents
ocfs2_ioctl_move_extents
ocfs2_move_extents
ocfs2_defrag_extent
ocfs2_lock_allocators_move_extents
ocfs2_reserve_clusters
inode_lock GLOBAL_BITMAP_SYSTEM_INODE
__ocfs2_flush_truncate_log
inode_lock GLOBAL_BITMAP_SYSTEM_INODE
As backtrace shows above, ocfs2_reserve_clusters() will call inode_lock against the global bitmap if local allocator has not sufficient cluters. Once global bitmap could meet the demand, ocfs2_reserve_cluster will return success with global bitmap locked.
After ocfs2_reserve_cluster(), if truncate log is full, __ocfs2_flush_truncate_log() will definitely fall into deadlock because it needs to inode_lock global bitmap, which has already been locked.
To fix this bug, we could remove from ocfs2_lock_allocators_move_extents() the code which intends to lock global allocator, and put the removed code after __ocfs2_flush_truncate_log().
ocfs2_lock_allocators_move_extents() is referred by 2 places, one is here, the other does not need the data allocator context, which means this patch does not affect the caller so far.
--- fs/ocfs2/move_extents.c | 47 +++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 21 deletions(-)
fs/ocfs2/move_extents.c +26 -21
@@ -156,18 +156,14 @@ static int __ocfs2_move_extent(handle_t *handle, }/* -* lock allocators, and reserving appropriate number of bits for -* meta blocks and data clusters. -* -* in some cases, we don't need to reserve clusters, just let data_ac -* be NULL. +* lock allocator, and reserve appropriate number of bits for +* meta blocks. */ -static int ocfs2_lock_allocators_move_extents (struct inode *inode, +static int ocfs2_lock_meta_allocator_move_extents (struct inode *inode,struct ocfs2_extent_tree *et,u32 clusters_to_move,u32 extents_to_split,struct ocfs2_alloc_context **meta_ac, -struct ocfs2_alloc_context **data_ac,int extra_blocks,int *credits) {
@@ -192,13 +188,6 @@ static int ocfs2_lock_allocators_move_extents(struct inode *inode, goto out; } -if (data_ac) { - ret =ocfs2_reserve_clusters (osb, clusters_to_move, data_ac); -if (ret) { -mlog_errno (ret); - goto out; - } - } *credits +=ocfs2_calc_extend_credits (osb->sb, et->et_root_el);
@@ -257,10 +246,10 @@ static int ocfs2_defrag_extent(struct ocfs2_move_extents_context *context, } } - ret =ocfs2_lock_allocators_move_extents (inode, &context->et, *len,1 , - &context->meta_ac, - &context->data_ac, - extra_blocks, &credits); + ret =ocfs2_lock_meta_allocator_move_extents (inode, &context->et, + *len,1 , + &context->meta_ac, + extra_blocks, &credits);if (ret) {mlog_errno (ret); goto out;
@@ -283,6 +272,21 @@ static int ocfs2_defrag_extent(struct ocfs2_move_extents_context *context, } } +/* +* Make sure ocfs2_reserve_cluster is called after +* __ocfs2_flush_truncate_log, otherwise, dead lock may happen. +* +* If ocfs2_reserve_cluster is called +* before __ocfs2_flush_truncate_log, dead lock on global bitmap +* may happen. +* +*/ + ret =ocfs2_reserve_clusters (osb, *len, &context->data_ac); +if (ret) { +mlog_errno (ret); + goto out_unlock_mutex; + } + handle =ocfs2_start_trans (osb, credits);if (IS_ERR (handle)) { ret =PTR_ERR (handle);
@@ -600,9 +604,10 @@ static int ocfs2_move_extent(struct ocfs2_move_extents_context *context, } } - ret =ocfs2_lock_allocators_move_extents (inode, &context->et, len,1 , - &context->meta_ac, -NULL , extra_blocks, &credits); + ret =ocfs2_lock_meta_allocator_move_extents (inode, &context->et, + len,1 , + &context->meta_ac, + extra_blocks, &credits);if (ret) {mlog_errno (ret); goto out;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 65/69 mm/page_alloc.c: fix calculation of pgdat->nr_zones
In reply to Sasha LevinFrom: Wei Yang <[email protected]>
[ Upstream commit 8f416836c0d50b198cad1225132e5abebf8980dc ]
init_currently_empty_zone() will adjust pgdat->nr_zones and set it to 'zone_idx(zone) + 1' unconditionally. This is correct in the normal case, while not exact in hot-plug situation.
This function is used in two places:
* free_area_init_core()
* move_pfn_range_to_zone()
In the first case, we are sure zone index increase monotonically. While in the second one, this is under users control.
One way to reproduce this is:
----------------------------
1. create a virtual machine with empty node1
-m 4G,slots=32,maxmem=32G \ -smp 4,maxcpus=8 \ -numa node,nodeid=0,mem=4G,cpus=0-3 \ -numa node,nodeid=1,mem=0G,cpus=4-7
2. hot-add cpu 3-7
cpu-add [3-7]
2. hot-add memory to nod1
object_add memory-backend-ram,id=ram0,size=1G
device_add pc-dimm,id=dimm0,memdev=ram0,node=1
3. online memory with following order
echo online_movable > memory47/state
echo online > memory40/state
After this, node1 will have its nr_zones equals to (ZONE_NORMAL + 1) instead of (ZONE_MOVABLE + 1).
Michal said:
"Having an incorrect nr_zones might result in all sorts of problems
which would be quite hard to debug (e.g. reclaim not considering the movable zone). I do not expect many users would suffer from this it but still this is trivial and obviously right thing to do so backporting to the stable tree shouldn't be harmful (last famous words)"
--- mm/page_alloc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
mm/page_alloc.c +3 -1
@@ -5554,8 +5554,10 @@ void __meminit init_currently_empty_zone(struct zone *zone, unsigned long size) {struct pglist_data *pgdat = zone->zone_pgdat; +int zone_idx =zone_idx (zone) +1 ; - pgdat->nr_zones =zone_idx (zone) +1 ; +if (zone_idx > pgdat->nr_zones) + pgdat->nr_zones = zone_idx; zone->zone_start_pfn = zone_start_pfn;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 66/69 hfs: do not free node before using
In reply to Sasha LevinFrom: Pan Bian <[email protected]>
[ Upstream commit ce96a407adef126870b3f4a1b73529dd8aa80f49 ]
hfs_bmap_free() frees the node via hfs_bnode_put(node). However, it then reads node->this when dumping error message on an error path, which may result in a use-after-free bug. This patch frees the node only when it is never again used.
--- fs/hfs/btree.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/hfs/btree.c +2 -1
@@ -329,13 +329,14 @@ void hfs_bmap_free(struct hfs_bnode *node) nidx -= len *8 ; i = node->next; -hfs_bnode_put (node);if (!i) {/* panic */ ;pr_crit ("unable to free bnode %u. bmap not found!\n" , node->this); +hfs_bnode_put (node);return ; } +hfs_bnode_put (node); node =hfs_bnode_find (tree, i);if (IS_ERR (node))return ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 67/69 hfsplus: do not free node before using
In reply to Sasha LevinFrom: Pan Bian <[email protected]>
[ Upstream commit c7d7d620dcbd2a1c595092280ca943f2fced7bbd ]
hfs_bmap_free() frees node via hfs_bnode_put(node). However it then reads node->this when dumping error message on an error path, which may result in a use-after-free bug. This patch frees node only when it is never used.
--- fs/hfsplus/btree.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/hfsplus/btree.c +2 -1
@@ -454,14 +454,15 @@ void hfs_bmap_free(struct hfs_bnode *node) nidx -= len *8 ; i = node->next; -hfs_bnode_put (node);if (!i) {/* panic */ ;pr_crit ("unable to free bnode %u. " "bmap not found!\n" , node->this); +hfs_bnode_put (node);return ; } +hfs_bnode_put (node); node =hfs_bnode_find (tree, i);if (IS_ERR (node))return ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 68/69 debugobjects: avoid recursive calls with kmemleak
In reply to Sasha LevinFrom: Qian Cai <[email protected]>
[ Upstream commit 8de456cf87ba863e028c4dd01bae44255ce3d835 ]
CONFIG_DEBUG_OBJECTS_RCU_HEAD does not play well with kmemleak due to recursive calls.
fill_pool
kmemleak_ignore
make_black_object
put_object
__call_rcu (kernel/rcu/tree.c)
debug_rcu_head_queue
debug_object_activate
debug_object_init
fill_pool
kmemleak_ignore
make_black_object
...So add SLAB_NOLEAKTRACE to kmem_cache_create() to not register newly allocated debug objects at all.
--- lib/debugobjects.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
lib/debugobjects.c +2 -3
@@ -111,7 +111,6 @@ static void fill_pool(void)if (!new)return ; -kmemleak_ignore (new);raw_spin_lock_irqsave (&pool_lock, flags);hlist_add_head (&new->node, &obj_pool); debug_objects_allocated++;
@@ -1085,7 +1084,6 @@ static int __init debug_objects_replace_static_objects(void) obj =kmem_cache_zalloc (obj_cache,GFP_KERNEL );if (!obj) goto free; -kmemleak_ignore (obj);hlist_add_head (&obj->node, &objects); }
@@ -1141,7 +1139,8 @@ void __init debug_objects_mem_init(void) obj_cache =kmem_cache_create ("debug_objects_cache" ,sizeof (struct debug_obj ),0 , -SLAB_DEBUG_OBJECTS ,NULL ); +SLAB_DEBUG_OBJECTS |SLAB_NOLEAKTRACE , +NULL );if (!obj_cache ||debug_objects_replace_static_objects ()) { debug_objects_enabled =0 ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 69/69 ocfs2: fix potential use after free
In reply to Sasha LevinFrom: Pan Bian <[email protected]>
[ Upstream commit 164f7e586739d07eb56af6f6d66acebb11f315c8 ]
ocfs2_get_dentry() calls iput(inode) to drop the reference count of inode, and if the reference count hits 0, inode is freed. However, in this function, it then reads inode->i_generation, which may result in a use after free bug. Move the put operation later.
--- fs/ocfs2/export.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ocfs2/export.c +1 -1
@@ -125,10 +125,10 @@ static struct dentry *ocfs2_get_dentry(struct super_block *sb, check_gen:if (handle->ih_generation != inode->i_generation) { -iput (inode);trace_ocfs2_get_dentry_generation ((unsigned long long )blkno, handle->ih_generation, inode->i_generation); +iput (inode); result =ERR_PTR (-ESTALE ); goto bail; }
Signature · 1 line
2.17.1