ARM: OMAP2+: prm44xx: Fix section annotation on omap44xx_prm_enable_io_wakeup
Subsystems (9)
Sasha Levin
maintainerPATCH 1/33 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/33 ARM: OMAP1: ams-delta: Fix possible use of uninitialized field
From: 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
@@ -511,6 +511,9 @@ static void modem_pm(struct uart_port *port, unsigned int state, unsigned old) {struct modem_private_data *priv = port->private_data; +if (!priv) +return ; +if (IS_ERR (priv->regulator))return ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 3/33 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 4/33 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
@@ -344,6 +344,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 5/33 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
@@ -273,7 +273,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 6/33 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
@@ -1711,6 +1711,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 7/33 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 8/33 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
@@ -3232,7 +3232,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)) {
@@ -3243,6 +3244,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)
@@ -3257,7 +3262,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);
@@ -3268,7 +3273,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 9/33 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
@@ -606,7 +606,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:
@@ -1892,10 +1892,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 10/33 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;
@@ -273,6 +275,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);
@@ -285,6 +290,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); }
@@ -296,7 +309,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);
@@ -336,14 +349,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)
@@ -358,6 +382,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);
@@ -419,6 +457,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 11/33 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 12/33 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
@@ -76,7 +76,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 13/33 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
@@ -119,11 +119,13 @@ static u64 bpf_trace_printk(u64 r1, u64 fmt_size, u64 r3, u64 r4, u64 r5) 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 14/33 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 15/33 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 16/33 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 17/33 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 18/33 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
@@ -56,7 +56,7 @@#define APIC_BUS_CYCLE_NS 1/* #define apic_debug(fmt,arg...) printk(KERN_WARNING fmt,##arg) */ -#define apic_debug(fmt, arg...) +#define apic_debug(fmt, arg...) do {} while (0)#define APIC_LVT_NUM 6/* 14 is the version for Xeon and Pentium 8.4.8*/
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 19/33 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
@@ -1090,6 +1090,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 20/33 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
@@ -1429,7 +1429,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 21/33 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
@@ -215,9 +215,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 22/33 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
@@ -919,10 +919,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 23/33 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
@@ -4519,8 +4519,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" );
@@ -4528,7 +4528,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);
@@ -4541,10 +4540,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) {
@@ -4557,16 +4561,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 24/33 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
@@ -968,9 +968,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 ; }
@@ -978,9 +990,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 ; }
@@ -993,7 +1017,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 ;
@@ -1009,7 +1033,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 25/33 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
@@ -34,6 +34,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 26/33 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 27/33 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
@@ -963,11 +963,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 28/33 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 29/33 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);
@@ -260,10 +249,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;
@@ -286,6 +275,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);
@@ -606,9 +610,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 30/33 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
@@ -328,13 +328,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 31/33 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
@@ -453,14 +453,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 32/33 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 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
lib/debugobjects.c +2 -1
@@ -1088,7 +1088,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 33/33 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