6.6.64-rc1 review
Subsystems (5)
Greg Kroah-Hartman
maintainerPATCH 527/676 block: fix ordering between checking QUEUE_FLAG_QUIESCED request adding
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Muchun Song <[email protected]>
commit 6bda857bcbb86fb9d0e54fbef93a093d51172acc upstream.
Supposing the following scenario.
CPU0 CPU1
blk_mq_insert_request() 1) store
blk_mq_unquiesce_queue()
blk_queue_flag_clear() 3) store
blk_mq_run_hw_queues()
blk_mq_run_hw_queue()
if (!blk_mq_hctx_has_pending()) 4) load
returnblk_mq_run_hw_queue()
if (blk_queue_quiesced()) 2) load
return
blk_mq_sched_dispatch_requests()
The full memory barrier should be inserted between 1) and 2), as well as between 3) and 4) to make sure that either CPU0 sees QUEUE_FLAG_QUIESCED is cleared or CPU1 sees dispatch list or setting of bitmap of software queue. Otherwise, either CPU will not rerun the hardware queue causing starvation.
So the first solution is to 1) add a pair of memory barrier to fix the problem, another solution is to 2) use hctx->queue->queue_lock to synchronize QUEUE_FLAG_QUIESCED. Here, we chose 2) to fix it since memory barrier is not easy to be maintained.
--- block/blk-mq.c | 49 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 14 deletions(-)
block/blk-mq.c +35 -14
@@ -2252,6 +2252,24 @@ void blk_mq_delay_run_hw_queue(struct bl }EXPORT_SYMBOL (blk_mq_delay_run_hw_queue); +static inline bool blk_mq_hw_queue_need_run (struct blk_mq_hw_ctx *hctx) +{ +bool need_run; + +/* +* When queue is quiesced, we may be switching io scheduler, or +* updating nr_hw_queues, or other things, and we can't run queue +* any more, even blk_mq_hctx_has_pending() can't be called safely. +* +* And queue will be rerun in blk_mq_unquiesce_queue() if it is +* quiesced. +*/ +__blk_mq_run_dispatch_ops (hctx->queue, false, + need_run = !blk_queue_quiesced (hctx->queue) && +blk_mq_hctx_has_pending (hctx)); +return need_run; +} +/** * blk_mq_run_hw_queue - Start to run a hardware queue. * @hctx: Pointer to the hardware queue to run.
@@ -2272,20 +2290,23 @@ void blk_mq_run_hw_queue(struct blk_mq_hmight_sleep_if (!async && hctx->flags &BLK_MQ_F_BLOCKING ); -/* -* When queue is quiesced, we may be switching io scheduler, or -* updating nr_hw_queues, or other things, and we can't run queue -* any more, even __blk_mq_hctx_has_pending() can't be called safely. -* -* And queue will be rerun in blk_mq_unquiesce_queue() if it is -* quiesced. -*/ -__blk_mq_run_dispatch_ops (hctx->queue, false, - need_run = !blk_queue_quiesced (hctx->queue) && -blk_mq_hctx_has_pending (hctx)); - -if (!need_run) -return ; + need_run =blk_mq_hw_queue_need_run (hctx); +if (!need_run) { +unsigned long flags; + +/* +* Synchronize with blk_mq_unquiesce_queue(), because we check +* if hw queue is quiesced locklessly above, we need the use +* ->queue_lock to make sure we see the up-to-date status to +* not miss rerunning the hw queue. +*/ +spin_lock_irqsave (&hctx->queue->queue_lock, flags); + need_run =blk_mq_hw_queue_need_run (hctx); +spin_unlock_irqrestore (&hctx->queue->queue_lock, flags); + +if (!need_run) +return ; + }if (async || !cpumask_test_cpu (raw_smp_processor_id (), hctx->cpumask)) {blk_mq_delay_run_hw_queue (hctx,0 );
Greg Kroah-Hartman
maintainerPATCH 528/676 block: fix ordering between checking BLK_MQ_S_STOPPED request adding
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Muchun Song <[email protected]>
commit 96a9fe64bfd486ebeeacf1e6011801ffe89dae18 upstream.
Supposing first scenario with a virtio_blk driver.
CPU0 CPU1
blk_mq_try_issue_directly()
__blk_mq_issue_directly()
q->mq_ops->queue_rq()
virtio_queue_rq()
blk_mq_stop_hw_queue()
virtblk_done()
blk_mq_request_bypass_insert() 1) store
blk_mq_start_stopped_hw_queue()
clear_bit(BLK_MQ_S_STOPPED) 3) store
blk_mq_run_hw_queue()
if (!blk_mq_hctx_has_pending()) 4) load
return
blk_mq_sched_dispatch_requests()
blk_mq_run_hw_queue()
if (!blk_mq_hctx_has_pending())
return
blk_mq_sched_dispatch_requests()
if (blk_mq_hctx_stopped()) 2) load
return
__blk_mq_sched_dispatch_requests()Supposing another scenario.
CPU0 CPU1
blk_mq_requeue_work()
blk_mq_insert_request() 1) store
virtblk_done()
blk_mq_start_stopped_hw_queue()
blk_mq_run_hw_queues() clear_bit(BLK_MQ_S_STOPPED) 3) store
blk_mq_run_hw_queue()
if (!blk_mq_hctx_has_pending()) 4) load
return
blk_mq_sched_dispatch_requests()
if (blk_mq_hctx_stopped()) 2) load
continue
blk_mq_run_hw_queue()Both scenarios are similar, the full memory barrier should be inserted between 1) and 2), as well as between 3) and 4) to make sure that either CPU0 sees BLK_MQ_S_STOPPED is cleared or CPU1 sees dispatch list. Otherwise, either CPU will not rerun the hardware queue causing starvation of the request.
The easy way to fix it is to add the essential full memory barrier into helper of blk_mq_hctx_stopped(). In order to not affect the fast path (hardware queue is not stopped most of the time), we only insert the barrier into the slow path. Actually, only slow path needs to care about missing of dispatching the request to the low-level device driver.
--- block/blk-mq.c | 6 ++++++ block/blk-mq.h | 13 +++++++++++++ 2 files changed, 19 insertions(+)
block/blk-mq.c +6 -0
@@ -2463,6 +2463,12 @@ void blk_mq_start_stopped_hw_queue(strucreturn ;clear_bit (BLK_MQ_S_STOPPED , &hctx->state); +/* +* Pairs with the smp_mb() in blk_mq_hctx_stopped() to order the +* clearing of BLK_MQ_S_STOPPED above and the checking of dispatch +* list in the subsequent routine. +*/ +smp_mb__after_atomic ();blk_mq_run_hw_queue (hctx, async); }EXPORT_SYMBOL_GPL (blk_mq_start_stopped_hw_queue);
block/blk-mq.h +13 -0
@@ -228,6 +228,19 @@ static inline struct blk_mq_tags *blk_mqstatic inline bool blk_mq_hctx_stopped (struct blk_mq_hw_ctx *hctx) { +/* Fast path: hardware queue is not stopped most of the time. */ +if (likely (!test_bit (BLK_MQ_S_STOPPED , &hctx->state))) +return false; + +/* +* This barrier is used to order adding of dispatch list before and +* the test of BLK_MQ_S_STOPPED below. Pairs with the memory barrier +* in blk_mq_start_stopped_hw_queue() so that dispatch code could +* either see BLK_MQ_S_STOPPED is cleared or dispatch list is not +* empty to avoid missing dispatching requests. +*/ +smp_mb (); +return test_bit (BLK_MQ_S_STOPPED , &hctx->state); }
Greg Kroah-Hartman
maintainerPATCH 529/676 blk-mq: Make blk_mq_quiesce_tagset() hold the tag list mutex less long
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
commit ccd9e252c515ac5a3ed04a414c95d1307d17f159 upstream.
Make sure that the tag_list_lock mutex is not held any longer than necessary. This change reduces latency if e.g. blk_mq_quiesce_tagset() is called concurrently from more than one thread. This function is used by the NVMe core and also by the UFS driver.
--- block/blk-mq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
block/blk-mq.c +2 -1
@@ -283,8 +283,9 @@ void blk_mq_quiesce_tagset(struct blk_mqif (!blk_queue_skip_tagset_quiesce (q))blk_mq_quiesce_queue_nowait (q); } -blk_mq_wait_quiesce_done (set);mutex_unlock (&set->tag_list_lock); + +blk_mq_wait_quiesce_done (set); }EXPORT_SYMBOL_GPL (blk_mq_quiesce_tagset);
Greg Kroah-Hartman
maintainerPATCH 530/676 HID: wacom: Interpret tilt data from Intuos Pro BT as signed values
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Gerecke <[email protected]>
commit 49a397ad24ee5e2c53a59dada2780d7e71bd3f77 upstream.
The tilt data contained in the Bluetooth packets of an Intuos Pro are supposed to be interpreted as signed values. Simply casting the values to type char is not guaranteed to work since it is implementation- defined whether it is signed or unsigned. At least one user has noticed the data being reported incorrectly on their system. To ensure that the data is interpreted properly, we specifically cast to signed char instead.
--- drivers/hid/wacom_wac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/hid/wacom_wac.c +2 -2
@@ -1399,9 +1399,9 @@ static void wacom_intuos_pro2_bt_pen(str rotation -=1800 ;input_report_abs (pen_input,ABS_TILT_X , - (char )frame[7 ]); + (signed char )frame[7 ]);input_report_abs (pen_input,ABS_TILT_Y , - (char )frame[8 ]); + (signed char )frame[8 ]);input_report_abs (pen_input,ABS_Z , rotation);input_report_abs (pen_input,ABS_WHEEL ,get_unaligned_le16 (&frame[11 ]));
Greg Kroah-Hartman
maintainerPATCH 531/676 media: wl128x: Fix atomicity violation in fmc_send_cmd()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qiu-ji Chen <[email protected]>
commit ca59f9956d4519ab18ab2270be47c6b8c6ced091 upstream.
Atomicity violation occurs when the fmc_send_cmd() function is executed simultaneously with the modification of the fmdev->resp_skb value. Consider a scenario where, after passing the validity check within the function, a non-null fmdev->resp_skb variable is assigned a null value. This results in an invalid fmdev->resp_skb variable passing the validity check. As seen in the later part of the function, skb = fmdev->resp_skb; when the invalid fmdev->resp_skb passes the check, a null pointer dereference error may occur at line 478, evt_hdr = (void *)skb->data;
To address this issue, it is recommended to include the validity check of fmdev->resp_skb within the locked section of the function. This modification ensures that the value of fmdev->resp_skb does not change during the validation process, thereby maintaining its validity.
This possible bug is found by an experimental static analysis tool developed by our team. This tool analyzes the locking APIs to extract function pairs that can be concurrently executed, and then analyzes the instructions in the paired functions to identify possible concurrency bugs including data races and atomicity violations.
--- drivers/media/radio/wl128x/fmdrv_common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/media/radio/wl128x/fmdrv_common.c +2 -1
@@ -466,11 +466,12 @@ int fmc_send_cmd(struct fmdev *fmdev, u8 jiffies_to_msecs(FM_DRV_TX_TIMEOUT) / 1000);return -ETIMEDOUT ; } +spin_lock_irqsave (&fmdev->resp_skb_lock, flags);if (!fmdev->resp_skb) { +spin_unlock_irqrestore (&fmdev->resp_skb_lock, flags);fmerr ("Response SKB is missing\n" );return -EFAULT ; } -spin_lock_irqsave (&fmdev->resp_skb_lock, flags); skb = fmdev->resp_skb; fmdev->resp_skb =NULL ;spin_unlock_irqrestore (&fmdev->resp_skb_lock, flags);
Greg Kroah-Hartman
maintainerPATCH 532/676 soc: fsl: rcpm: fix missing of_node_put() in copy_ippdexpcr1_setting()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Carrasco <[email protected]>
commit c9f1efabf8e3b3ff886a42669f7093789dbeca94 upstream.
of_find_compatible_node() requires a call to of_node_put() when the pointer to the node is not required anymore to decrement its refcount and avoid leaking memory.
Add the missing call to of_node_put() after the node has been used.
--- drivers/soc/fsl/rcpm.c | 1 + 1 file changed, 1 insertion(+)
drivers/soc/fsl/rcpm.c +1 -0
@@ -36,6 +36,7 @@ static void copy_ippdexpcr1_setting(u32return ; regs =of_iomap (np,0 ); +of_node_put (np);if (!regs)return ;
Greg Kroah-Hartman
maintainerPATCH 533/676 media: v4l2-core: v4l2-dv-timings: check cvt/gtf result
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans Verkuil <[email protected]>
commit 9f070b1862f3411b8bcdfd51a8eaad25286f9deb upstream.
The v4l2_detect_cvt/gtf functions should check the result against the timing capabilities: these functions calculate the timings, so if they are out of bounds, they should be rejected.
To do this, add the struct v4l2_dv_timings_cap as argument to those functions.
This required updates to the adv7604 and adv7842 drivers since the prototype of these functions has now changed. The timings struct that is passed to v4l2_detect_cvt/gtf in those two drivers is filled with the timings detected by the hardware.
The vivid driver was also updated, but an additional check was added:
the width and height specified by VIDIOC_S_DV_TIMINGS has to match the calculated result, otherwise something went wrong. Note that vivid *emulates* hardware, so all the values passed to the v4l2_detect_cvt/gtf functions came from the timings struct that was filled by userspace and passed on to the driver via VIDIOC_S_DV_TIMINGS. So these fields can contain random data. Both the constraints check via struct v4l2_dv_timings_cap and the additional width/height check ensure that the resulting timings are sane and not messed up by the v4l2_detect_cvt/gtf calculations.
--- drivers/media/i2c/adv7604.c | 5 drivers/media/i2c/adv7842.c | 13 +- drivers/media/test-drivers/vivid/vivid-vid-cap.c | 15 ++ drivers/media/v4l2-core/v4l2-dv-timings.c | 132 ++++++++++++----------- include/media/v4l2-dv-timings.h | 18 ++- 5 files changed, 107 insertions(+), 76 deletions(-)
drivers/media/i2c/adv7604.c +3 -2
@@ -1405,12 +1405,13 @@ static int stdi2dv_timings(struct v4l2_sif (v4l2_detect_cvt (stdi->lcf +1 , hfreq, stdi->lcvs,0 , (stdi->hs_pol =='+' ?V4L2_DV_HSYNC_POS_POL :0 ) | (stdi->vs_pol =='+' ?V4L2_DV_VSYNC_POS_POL :0 ), - false, timings)) + false,adv76xx_get_dv_timings_cap (sd,-1 ), timings))return 0 ;if (v4l2_detect_gtf (stdi->lcf +1 , hfreq, stdi->lcvs, (stdi->hs_pol =='+' ?V4L2_DV_HSYNC_POS_POL :0 ) | (stdi->vs_pol =='+' ?V4L2_DV_VSYNC_POS_POL :0 ), - false, state->aspect_ratio, timings)) + false, state->aspect_ratio, +adv76xx_get_dv_timings_cap (sd,-1 ), timings))return 0 ; v4l2_dbg(2, debug, sd,
drivers/media/i2c/adv7842.c +7 -6
@@ -1431,14 +1431,15 @@ static int stdi2dv_timings(struct v4l2_s }if (v4l2_detect_cvt (stdi->lcf +1 , hfreq, stdi->lcvs,0 , - (stdi->hs_pol =='+' ?V4L2_DV_HSYNC_POS_POL :0 ) | - (stdi->vs_pol =='+' ?V4L2_DV_VSYNC_POS_POL :0 ), - false, timings)) + (stdi->hs_pol =='+' ?V4L2_DV_HSYNC_POS_POL :0 ) | + (stdi->vs_pol =='+' ?V4L2_DV_VSYNC_POS_POL :0 ), + false,adv7842_get_dv_timings_cap (sd), timings))return 0 ;if (v4l2_detect_gtf (stdi->lcf +1 , hfreq, stdi->lcvs, - (stdi->hs_pol =='+' ?V4L2_DV_HSYNC_POS_POL :0 ) | - (stdi->vs_pol =='+' ?V4L2_DV_VSYNC_POS_POL :0 ), - false, state->aspect_ratio, timings)) + (stdi->hs_pol =='+' ?V4L2_DV_HSYNC_POS_POL :0 ) | + (stdi->vs_pol =='+' ?V4L2_DV_VSYNC_POS_POL :0 ), + false, state->aspect_ratio, +adv7842_get_dv_timings_cap (sd), timings))return 0 ; v4l2_dbg(2, debug, sd,
drivers/media/test-drivers/vivid/vivid-vid-cap.c +13 -2
@@ -1466,12 +1466,19 @@ static bool valid_cvt_gtf_timings(struct h_freq = (u32 )bt->pixelclock / total_h_pixel;if (bt->standards ==0 || (bt->standards &V4L2_DV_BT_STD_CVT )) { +struct v4l2_dv_timings cvt = {}; +if (v4l2_detect_cvt (total_v_lines, h_freq, bt->vsync, bt->width, - bt->polarities, bt->interlaced, timings)) + bt->polarities, bt->interlaced, + &vivid_dv_timings_cap, &cvt) && + cvt.bt.width == bt->width && cvt.bt.height == bt->height) { + *timings = cvt;return true; + } }if (bt->standards ==0 || (bt->standards &V4L2_DV_BT_STD_GTF )) { +struct v4l2_dv_timings gtf = {};struct v4l2_fract aspect_ratio; find_aspect_ratio(bt->width, bt->height,
@@ -1479,8 +1486,12 @@ static bool valid_cvt_gtf_timings(struct &aspect_ratio.denominator);if (v4l2_detect_gtf (total_v_lines, h_freq, bt->vsync, bt->polarities, bt->interlaced, - aspect_ratio, timings)) + aspect_ratio, &vivid_dv_timings_cap, + >f) && + gtf.bt.width == bt->width && gtf.bt.height == bt->height) { + *timings = gtf;return true; + } }return false; }
drivers/media/v4l2-core/v4l2-dv-timings.c +72 -60
191 lines not on this page · raw message
include/media/v4l2-dv-timings.h +12 -6
@@ -146,15 +146,18 @@ void v4l2_print_dv_timings(const char *d* @polarities: the horizontal and vertical polarities (same as struct * v4l2_bt_timings polarities). * @interlaced: if this flag is true, it indicates interlaced format +* @cap: the v4l2_dv_timings_cap capabilities. * @fmt: the resulting timings. * * This function will attempt to detect if the given values correspond to a * valid CVT format. If so, then it will return true, and fmt will be filled * in with the found CVT timings. */ -bool v4l2_detect_cvt (unsigned frame_height,unsigned hfreq,unsigned vsync, -unsigned active_width,u32 polarities,bool interlaced, -struct v4l2_dv_timings *fmt); +bool v4l2_detect_cvt (unsigned int frame_height,unsigned int hfreq, +unsigned int vsync,unsigned int active_width, +u32 polarities,bool interlaced, +const struct v4l2_dv_timings_cap *cap, +struct v4l2_dv_timings *fmt);/** * v4l2_detect_gtf - detect if the given timings follow the GTF standard
@@ -170,15 +173,18 @@ bool v4l2_detect_cvt(unsigned frame_heig* image height, so it has to be passed explicitly. Usually * the native screen aspect ratio is used for this. If it * is not filled in correctly, then 16:9 will be assumed. +* @cap: the v4l2_dv_timings_cap capabilities. * @fmt: the resulting timings. * * This function will attempt to detect if the given values correspond to a * valid GTF format. If so, then it will return true, and fmt will be filled * in with the found GTF timings. */ -bool v4l2_detect_gtf (unsigned frame_height,unsigned hfreq,unsigned vsync, -u32 polarities,bool interlaced,struct v4l2_fract aspect, -struct v4l2_dv_timings *fmt); +bool v4l2_detect_gtf (unsigned int frame_height,unsigned int hfreq, +unsigned int vsync,u32 polarities,bool interlaced, +struct v4l2_fract aspect, +const struct v4l2_dv_timings_cap *cap, +struct v4l2_dv_timings *fmt);/** * v4l2_calc_aspect_ratio - calculate the aspect ratio based on bytes
Greg Kroah-Hartman
maintainerPATCH 534/676 ALSA: ump: Fix evaluation of MIDI 1.0 FB info
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 7be34f6feedd60e418de1c2c48e661d70416635f upstream.
The m1.0 field of UMP Function Block info specifies whether the given FB is a MIDI 1.0 port or not. When implementing the UMP support on Linux, I somehow interpreted as if it were bit flags, but the field is actually an enumeration from 0 to 2, where 2 means MIDI 1.0 *and* low speed.
This patch corrects the interpretation and sets the right bit flags depending on the m1.0 field of FB Info. This effectively fixes the missing detection of MIDI 1.0 FB when m1.0 is 2.
--- sound/core/ump.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
sound/core/ump.c +4 -1
@@ -724,7 +724,10 @@ static void fill_fb_info(struct snd_ump_ info->ui_hint = buf->fb_info.ui_hint; info->first_group = buf->fb_info.first_group; info->num_groups = buf->fb_info.num_groups; - info->flags = buf->fb_info.midi_10; +if (buf->fb_info.midi_10 <2 ) + info->flags = buf->fb_info.midi_10; +else + info->flags =SNDRV_UMP_BLOCK_IS_MIDI1 |SNDRV_UMP_BLOCK_IS_LOWSPEED ; info->active = buf->fb_info.active; info->midi_ci_version = buf->fb_info.midi_ci_version; info->sysex8_streams = buf->fb_info.sysex8_streams;
Greg Kroah-Hartman
maintainerPATCH 535/676 ALSA: pcm: Add sanity NULL check for the default mmap fault handler
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit d2913a07d9037fe7aed4b7e680684163eaed6bc4 upstream.
A driver might allow the mmap access before initializing its runtime->dma_area properly. Add a proper NULL check before passing to virt_to_page() for avoiding a panic.
--- sound/core/pcm_native.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
sound/core/pcm_native.c +4 -2
@@ -3794,9 +3794,11 @@ static vm_fault_t snd_pcm_mmap_data_faulreturn VM_FAULT_SIGBUS ;if (substream->ops->page) page = substream->ops->page (substream, offset); -else if (!snd_pcm_get_dma_buf (substream)) +else if (!snd_pcm_get_dma_buf (substream)) { +if (WARN_ON_ONCE (!runtime->dma_area)) +return VM_FAULT_SIGBUS ; page =virt_to_page (runtime->dma_area + offset); -else + }else page =snd_sgbuf_get_page (snd_pcm_get_dma_buf (substream), offset);if (!page)return VM_FAULT_SIGBUS ;
Greg Kroah-Hartman
maintainerPATCH 536/676 ALSA: hda/realtek: Update ALC225 depop procedure
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kailang Yang <[email protected]>
commit 1fd50509fe14a9adc9329e0454b986157a4c155a upstream.
Old procedure has a chance to meet Headphone no output.
--- sound/pci/hda/patch_realtek.c | 95 +++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 52 deletions(-)
sound/pci/hda/patch_realtek.c +43 -52
@@ -3757,33 +3757,28 @@ static void alc225_init(struct hda_codec hp1_pin_sense =snd_hda_jack_detect (codec, hp_pin); hp2_pin_sense =snd_hda_jack_detect (codec,0x16 ); -if (hp1_pin_sense || hp2_pin_sense) +if (hp1_pin_sense || hp2_pin_sense) {msleep (2 ); +alc_update_coefex_idx (codec,0x57 ,0x04 ,0x0007 ,0x1 );/* Low power */ -alc_update_coefex_idx (codec,0x57 ,0x04 ,0x0007 ,0x1 );/* Low power */ +if (hp1_pin_sense) +snd_hda_codec_write (codec, hp_pin,0 , +AC_VERB_SET_PIN_WIDGET_CONTROL ,PIN_OUT ); +if (hp2_pin_sense) +snd_hda_codec_write (codec,0x16 ,0 , +AC_VERB_SET_PIN_WIDGET_CONTROL ,PIN_OUT ); +msleep (75 ); + +if (hp1_pin_sense) +snd_hda_codec_write (codec, hp_pin,0 , +AC_VERB_SET_AMP_GAIN_MUTE ,AMP_OUT_UNMUTE ); +if (hp2_pin_sense) +snd_hda_codec_write (codec,0x16 ,0 , +AC_VERB_SET_AMP_GAIN_MUTE ,AMP_OUT_UNMUTE ); -if (hp1_pin_sense || spec->ultra_low_power) -snd_hda_codec_write (codec, hp_pin,0 , -AC_VERB_SET_AMP_GAIN_MUTE ,AMP_OUT_MUTE ); -if (hp2_pin_sense) -snd_hda_codec_write (codec,0x16 ,0 , -AC_VERB_SET_AMP_GAIN_MUTE ,AMP_OUT_MUTE ); - -if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power) -msleep (85 ); - -if (hp1_pin_sense || spec->ultra_low_power) -snd_hda_codec_write (codec, hp_pin,0 , -AC_VERB_SET_PIN_WIDGET_CONTROL ,PIN_OUT ); -if (hp2_pin_sense) -snd_hda_codec_write (codec,0x16 ,0 , -AC_VERB_SET_PIN_WIDGET_CONTROL ,PIN_OUT ); - -if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power) -msleep (100 ); - -alc_update_coef_idx (codec,0x4a ,3 <<10 ,0 ); -alc_update_coefex_idx (codec,0x57 ,0x04 ,0x0007 ,0x4 );/* Hight power */ +msleep (75 ); +alc_update_coefex_idx (codec,0x57 ,0x04 ,0x0007 ,0x4 );/* Hight power */ + } }static void alc225_shutup (struct hda_codec *codec)
@@ -3795,36 +3790,35 @@ static void alc225_shutup(struct hda_codif (!hp_pin) hp_pin =0x21 ; -alc_disable_headset_jack_key (codec); -/* 3k pull low control for Headset jack. */ -alc_update_coef_idx (codec,0x4a ,0 ,3 <<10 ); - hp1_pin_sense =snd_hda_jack_detect (codec, hp_pin); hp2_pin_sense =snd_hda_jack_detect (codec,0x16 ); -if (hp1_pin_sense || hp2_pin_sense) +if (hp1_pin_sense || hp2_pin_sense) { +alc_disable_headset_jack_key (codec); +/* 3k pull low control for Headset jack. */ +alc_update_coef_idx (codec,0x4a ,0 ,3 <<10 );msleep (2 ); -if (hp1_pin_sense || spec->ultra_low_power) -snd_hda_codec_write (codec, hp_pin,0 , -AC_VERB_SET_AMP_GAIN_MUTE ,AMP_OUT_MUTE ); -if (hp2_pin_sense) -snd_hda_codec_write (codec,0x16 ,0 , -AC_VERB_SET_AMP_GAIN_MUTE ,AMP_OUT_MUTE ); - -if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power) -msleep (85 ); - -if (hp1_pin_sense || spec->ultra_low_power) -snd_hda_codec_write (codec, hp_pin,0 , -AC_VERB_SET_PIN_WIDGET_CONTROL ,0x0 ); -if (hp2_pin_sense) -snd_hda_codec_write (codec,0x16 ,0 , -AC_VERB_SET_PIN_WIDGET_CONTROL ,0x0 ); - -if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power) -msleep (100 ); - +if (hp1_pin_sense) +snd_hda_codec_write (codec, hp_pin,0 , +AC_VERB_SET_AMP_GAIN_MUTE ,AMP_OUT_MUTE ); +if (hp2_pin_sense) +snd_hda_codec_write (codec,0x16 ,0 , +AC_VERB_SET_AMP_GAIN_MUTE ,AMP_OUT_MUTE ); + +msleep (75 ); + +if (hp1_pin_sense) +snd_hda_codec_write (codec, hp_pin,0 , +AC_VERB_SET_PIN_WIDGET_CONTROL ,0x0 ); +if (hp2_pin_sense) +snd_hda_codec_write (codec,0x16 ,0 , +AC_VERB_SET_PIN_WIDGET_CONTROL ,0x0 ); + +msleep (75 ); +alc_update_coef_idx (codec,0x4a ,3 <<10 ,0 ); +alc_enable_headset_jack_key (codec); + }alc_auto_setup_eapd (codec, false);alc_shutup_pins (codec);if (spec->ultra_low_power) {
@@ -3835,9 +3829,6 @@ static void alc225_shutup(struct hda_codalc_update_coef_idx (codec,0x4a ,3 <<4 ,2 <<4 );msleep (30 ); } - -alc_update_coef_idx (codec,0x4a ,3 <<10 ,0 ); -alc_enable_headset_jack_key (codec); }static void alc_default_init (struct hda_codec *codec)
Greg Kroah-Hartman
maintainerPATCH 537/676 ALSA: hda/realtek: Set PCBeep to default value for ALC274
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kailang Yang <[email protected]>
commit 155699ccab7c78cbba69798242b68bc8ac66d5d2 upstream.
BIOS Enable PC beep path cause pop noise via speaker during boot time. Set to default value from driver will solve the issue.
--- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+)
sound/pci/hda/patch_realtek.c +2 -0
@@ -471,6 +471,8 @@ static void alc_fill_eapd_coef(struct hdbreak ;case 0x10ec0234 :case 0x10ec0274 : +alc_write_coef_idx (codec,0x6e ,0x0c25 ); + fallthrough;case 0x10ec0294 :case 0x10ec0700 :case 0x10ec0701 :
Greg Kroah-Hartman
maintainerPATCH 538/676 ALSA: hda/realtek: Fix Internal Speaker and Mic boost of Infinix Y4 Max
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dinesh Kumar <[email protected]>
commit 5ebe792a5139f1ce6e4aed22bef12e7e2660df96 upstream.
Internal Speaker of Infinix Y4 Max remains muted due to incorrect Pin configuration, and the Internal Mic records high noise. This patch corrects the Pin configuration for the Internal Speaker and limits the Internal Mic boost.
HW Probe for device: https://linux-hardware.org/?probe=6d4386c347
Test: Internal Speaker works fine, Mic has low noise.
--- sound/pci/hda/patch_realtek.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
sound/pci/hda/patch_realtek.c +11 -0
@@ -7255,6 +7255,7 @@ enum {ALC269_FIXUP_THINKPAD_ACPI ,ALC269_FIXUP_DMIC_THINKPAD_ACPI ,ALC269VB_FIXUP_INFINIX_ZERO_BOOK_13 , +ALC269VC_FIXUP_INFINIX_Y4_MAX ,ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO ,ALC255_FIXUP_ACER_MIC_NO_PRESENCE , ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
@@ -7644,6 +7645,15 @@ static const struct hda_fixup alc269_fix .chained = true, .chain_id =ALC269_FIXUP_LIMIT_INT_MIC_BOOST }, + [ALC269VC_FIXUP_INFINIX_Y4_MAX] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl []) { + {0x1b ,0x90170150 },/* use as internal speaker */ + { } + }, + .chained = true, + .chain_id =ALC269_FIXUP_LIMIT_INT_MIC_BOOST + }, [ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO] = { .type = HDA_FIXUP_PINS, .v.pins = (const struct hda_pintbl []) {
@@ -10414,6 +10424,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x2782 ,0x0214 ,"VAIO VJFE-CL" ,ALC269_FIXUP_LIMIT_INT_MIC_BOOST ),SND_PCI_QUIRK (0x2782 ,0x0228 ,"Infinix ZERO BOOK 13" ,ALC269VB_FIXUP_INFINIX_ZERO_BOOK_13 ),SND_PCI_QUIRK (0x2782 ,0x0232 ,"CHUWI CoreBook XPro" ,ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO ), +SND_PCI_QUIRK (0x2782 ,0x1701 ,"Infinix Y4 Max" ,ALC269VC_FIXUP_INFINIX_Y4_MAX ),SND_PCI_QUIRK (0x2782 ,0x1707 ,"Vaio VJFE-ADL" ,ALC298_FIXUP_SPK_VOLUME ),SND_PCI_QUIRK (0x8086 ,0x2074 ,"Intel NUC 8" ,ALC233_FIXUP_INTEL_NUC8_DMIC ), SND_PCI_QUIRK(0x8086, 0x2080, "Intel NUC 8 Rugged", ALC256_FIXUP_INTEL_NUC8_RUGGED),
Greg Kroah-Hartman
maintainerPATCH 539/676 ALSA: hda/realtek: Apply quirk for Medion E15433
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit ca0f79f0286046f6a91c099dc941cf7afae198d6 upstream.
Medion E15433 laptop wich ALC269VC (SSID 2782:1705) needs the same workaround for the missing speaker as another model.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -10425,6 +10425,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x2782 ,0x0228 ,"Infinix ZERO BOOK 13" ,ALC269VB_FIXUP_INFINIX_ZERO_BOOK_13 ),SND_PCI_QUIRK (0x2782 ,0x0232 ,"CHUWI CoreBook XPro" ,ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO ),SND_PCI_QUIRK (0x2782 ,0x1701 ,"Infinix Y4 Max" ,ALC269VC_FIXUP_INFINIX_Y4_MAX ), +SND_PCI_QUIRK (0x2782 ,0x1705 ,"MEDION E15433" ,ALC269VC_FIXUP_INFINIX_Y4_MAX ),SND_PCI_QUIRK (0x2782 ,0x1707 ,"Vaio VJFE-ADL" ,ALC298_FIXUP_SPK_VOLUME ),SND_PCI_QUIRK (0x8086 ,0x2074 ,"Intel NUC 8" ,ALC233_FIXUP_INTEL_NUC8_DMIC ), SND_PCI_QUIRK(0x8086, 0x2080, "Intel NUC 8 Rugged", ALC256_FIXUP_INTEL_NUC8_RUGGED),
Greg Kroah-Hartman
maintainerPATCH 540/676 smb3: request handle caching when caching directories
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steve French <[email protected]>
commit 9ed9d83a51a9636d367c796252409e7b2f4de4d4 upstream.
This client was only requesting READ caching, not READ and HANDLE caching in the LeaseState on the open requests we send for directories. To delay closing a handle (e.g. for caching directory contents) we should be requesting HANDLE as well as READ (as we already do for deferred
close of files). See MS-SMB2 3.3.1.4 e.g.
--- fs/smb/client/smb2ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/smb/client/smb2ops.c +1 -1
@@ -4016,7 +4016,7 @@ map_oplock_to_lease(u8 oplock)if (oplock ==SMB2_OPLOCK_LEVEL_EXCLUSIVE )return SMB2_LEASE_WRITE_CACHING_LE |SMB2_LEASE_READ_CACHING_LE ;else if (oplock ==SMB2_OPLOCK_LEVEL_II ) -return SMB2_LEASE_READ_CACHING_LE ; +return SMB2_LEASE_READ_CACHING_LE |SMB2_LEASE_HANDLE_CACHING_LE ;else if (oplock ==SMB2_OPLOCK_LEVEL_BATCH )return SMB2_LEASE_HANDLE_CACHING_LE |SMB2_LEASE_READ_CACHING_LE |SMB2_LEASE_WRITE_CACHING_LE ;
Greg Kroah-Hartman
maintainerPATCH 541/676 smb: client: handle max length for SMB symlinks
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <[email protected]>
commit 0812340811e45ec4039d409049be53056182a552 upstream.
We can't use PATH_MAX for SMB symlinks because
(1) Windows Server will fail FSCTL_SET_REPARSE_POINT with STATUS_IO_REPARSE_DATA_INVALID when input buffer is larger than 16K, as specified in MS-FSA 2.1.5.10.37.
(2) The client won't be able to parse large SMB responses that includes SMB symlink path within SMB2_CREATE or SMB2_IOCTL responses.
Fix this by defining a maximum length value (4060) for SMB symlinks that both client and server can handle.
--- fs/smb/client/reparse.c | 5 ++++- fs/smb/client/reparse.h | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-)
fs/smb/client/reparse.c +4 -1
@@ -35,6 +35,9 @@ int smb2_create_reparse_symlink(const unu16 len, plen;int rc =0 ; +if (strlen (symname) >REPARSE_SYM_PATH_MAX ) +return -ENAMETOOLONG ; + sym =kstrdup (symname,GFP_KERNEL );if (!sym)return -ENOMEM ;
@@ -64,7 +67,7 @@ int smb2_create_reparse_symlink(const unif (rc <0 ) goto out; - plen =2 *UniStrnlen ((wchar_t *)path,PATH_MAX ); + plen =2 *UniStrnlen ((wchar_t *)path,REPARSE_SYM_PATH_MAX ); len =sizeof (*buf) + plen *2 ; buf =kzalloc (len,GFP_KERNEL );if (!buf) {
fs/smb/client/reparse.h +2 -0
@@ -12,6 +12,8 @@#include "fs_context.h" #include "cifsglob.h" +#define REPARSE_SYM_PATH_MAX 4060 +/* * Used only by cifs.ko to ignore reparse points from files when client or * server doesn't support FSCTL_GET_REPARSE_POINT.
Greg Kroah-Hartman
maintainerPATCH 542/676 smb: Dont leak cfid when reconnect races with open_cached_dir
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Aurich <[email protected]>
commit 7afb86733685c64c604d32faf00fa4a1f22c2ab1 upstream.
open_cached_dir() may either race with the tcon reconnection even before compound_send_recv() or directly trigger a reconnection via SMB2_open_init() or SMB_query_info_init().
The reconnection process invokes invalidate_all_cached_dirs() via cifs_mark_open_files_invalid(), which removes all cfids from the cfids->entries list but doesn't drop a ref if has_lease isn't true. This results in the currently-being-constructed cfid not being on the list, but still having a refcount of 2. It leaks if returned from open_cached_dir().
Fix this by setting cfid->has_lease when the ref is actually taken; the cfid will not be used by other threads until it has a valid time.
Addresses these kmemleaks:
unreferenced object 0xffff8881090c4000 (size 1024):
comm "bash", pid 1860, jiffies 4295126592 hex dump (first 32 bytes):
00 01 00 00 00 00 ad de 22 01 00 00 00 00 ad de ........".......
00 ca 45 22 81 88 ff ff f8 dc 4f 04 81 88 ff ff ..E"......O.....
backtrace (crc 6f58c20f):
[<ffffffff8b895a1e>] __kmalloc_cache_noprof+0x2be/0x350
[<ffffffff8bda06e3>] open_cached_dir+0x993/0x1fb0
[<ffffffff8bdaa750>] cifs_readdir+0x15a0/0x1d50
[<ffffffff8b9a853f>] iterate_dir+0x28f/0x4b0
[<ffffffff8b9a9aed>] __x64_sys_getdents64+0xfd/0x200
[<ffffffff8cf6da05>] do_syscall_64+0x95/0x1a0
[<ffffffff8d00012f>] entry_SYSCALL_64_after_hwframe+0x76/0x7eunreferenced object 0xffff8881044fdcf8 (size 8):
comm "bash", pid 1860, jiffies 4295126592
hex dump (first 8 bytes):
00 cc cc cc cc cc cc cc ........
backtrace (crc 10c106a9):
[<ffffffff8b89a3d3>] __kmalloc_node_track_caller_noprof+0x363/0x480
[<ffffffff8b7d7256>] kstrdup+0x36/0x60
[<ffffffff8bda0700>] open_cached_dir+0x9b0/0x1fb0
[<ffffffff8bdaa750>] cifs_readdir+0x15a0/0x1d50
[<ffffffff8b9a853f>] iterate_dir+0x28f/0x4b0
[<ffffffff8b9a9aed>] __x64_sys_getdents64+0xfd/0x200
[<ffffffff8cf6da05>] do_syscall_64+0x95/0x1a0
[<ffffffff8d00012f>] entry_SYSCALL_64_after_hwframe+0x76/0x7eAnd addresses these BUG splats when unmounting the SMB filesystem:
BUG: Dentry ffff888140590ba0{i=1000000000080,n=/} still in use (2) [unmount of cifs cifs]
WARNING: CPU: 3 PID: 3433 at fs/dcache.c:1536 umount_check+0xd0/0x100
Modules linked in:
CPU: 3 UID: 0 PID: 3433 Comm: bash Not tainted 6.12.0-rc4-g850925a8133c-dirty #49
Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 11/12/2020
RIP: 0010:umount_check+0xd0/0x100
Code: 8d 7c 24 40 e8 31 5a f4 ff 49 8b 54 24 40 41 56 49 89 e9 45 89 e8 48 89 d9 41 57 48 89 de 48 c7 c7 80 e7 db ac e8 f0 72 9a ff <0f> 0b 58 31 c0 5a 5b 5d 41 5c 41 5d 41 5e 41 5f e9 2b e5 5d 01 41
RSP: 0018:ffff88811cc27978 EFLAGS: 00010286
RAX: 0000000000000000 RBX: ffff888140590ba0 RCX: ffffffffaaf20bae
RDX: dffffc0000000000 RSI: 0000000000000008 RDI: ffff8881f6fb6f40
RBP: ffff8881462ec000 R08: 0000000000000001 R09: ffffed1023984ee3
R10: ffff88811cc2771f R11: 00000000016cfcc0 R12: ffff888134383e08
R13: 0000000000000002 R14: ffff8881462ec668 R15: ffffffffaceab4c0
FS: 00007f23bfa98740(0000) GS:ffff8881f6f80000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000556de4a6f808 CR3: 0000000123c80000 CR4: 0000000000350ef0
Call Trace:
<TASK>
d_walk+0x6a/0x530
shrink_dcache_for_umount+0x6a/0x200
generic_shutdown_super+0x52/0x2a0
kill_anon_super+0x22/0x40
cifs_kill_sb+0x159/0x1e0
deactivate_locked_super+0x66/0xe0
cleanup_mnt+0x140/0x210
task_work_run+0xfb/0x170
syscall_exit_to_user_mode+0x29f/0x2b0
do_syscall_64+0xa1/0x1a0
entry_SYSCALL_64_after_hwframe+0x76/0x7e
RIP: 0033:0x7f23bfb93ae7
Code: ff ff ff ff c3 66 0f 1f 44 00 00 48 8b 0d 11 93 0d 00 f7 d8 64 89 01 b8 ff ff ff ff eb bf 0f 1f 44 00 00 b8 50 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d e9 92 0d 00 f7 d8 64 89 01 48
RSP: 002b:00007ffee9138598 EFLAGS: 00000246 ORIG_RAX: 0000000000000050
RAX: 0000000000000000 RBX: 0000558f1803e9a0 RCX: 00007f23bfb93ae7
RDX: 0000000000000000 RSI: 0000000000000004 RDI: 0000558f1803e9a0
RBP: 0000558f1803e600 R08: 0000000000000007 R09: 0000558f17fab610
R10: d91d5ec34ab757b0 R11: 0000000000000246 R12: 0000000000000001
R13: 0000000000000000 R14: 0000000000000015 R15: 0000000000000000
</TASK>
irq event stamp: 1163486
hardirqs last enabled at (1163485): [<ffffffffac98d344>] _raw_spin_unlock_irqrestore+0x34/0x60
hardirqs last disabled at (1163486): [<ffffffffac97dcfc>] __schedule+0xc7c/0x19a0
softirqs last enabled at (1163482): [<ffffffffab79a3ee>] __smb_send_rqst+0x3de/0x990
softirqs last disabled at (1163480): [<ffffffffac2314f1>] release_sock+0x21/0xf0
---[ end trace 0000000000000000 ]---VFS: Busy inodes after unmount of cifs (cifs)
------------[ cut here ]------------ kernel BUG at fs/super.c:661! Oops: invalid opcode: 0000 [#1] PREEMPT SMP KASAN NOPTI CPU: 1 UID: 0 PID: 3433 Comm: bash Tainted: G W 6.12.0-rc4-g850925a8133c-dirty #49 Tainted: [W]=WARN Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 11/12/2020 RIP: 0010:generic_shutdown_super+0x290/0x2a0 Code: e8 15 7c f7 ff 48 8b 5d 28 48 89 df e8 09 7c f7 ff 48 8b 0b 48 89 ee 48 8d 95 68 06 00 00 48 c7 c7 80 7f db ac e8 00 69 af ff <0f> 0b 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 90 90 90 90 90 90 RSP: 0018:ffff88811cc27a50 EFLAGS: 00010246 RAX: 000000000000003e RBX: ffffffffae994420 RCX: 0000000000000027 RDX: 0000000000000000 RSI: ffffffffab06180e RDI: ffff8881f6eb18c8 RBP: ffff8881462ec000 R08: 0000000000000001 R09: ffffed103edd6319 R10: ffff8881f6eb18cb R11: 00000000016d3158 R12: ffff8881462ec9c0 R13: ffff8881462ec050 R14: 0000000000000001 R15: 0000000000000000 FS: 00007f23bfa98740(0000) GS:ffff8881f6e80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f8364005d68 CR3: 0000000123c80000 CR4: 0000000000350ef0 Call Trace: <TASK> kill_anon_super+0x22/0x40 cifs_kill_sb+0x159/0x1e0 deactivate_locked_super+0x66/0xe0 cleanup_mnt+0x140/0x210 task_work_run+0xfb/0x170 syscall_exit_to_user_mode+0x29f/0x2b0 do_syscall_64+0xa1/0x1a0 entry_SYSCALL_64_after_hwframe+0x76/0x7e RIP: 0033:0x7f23bfb93ae7 </TASK> Modules linked in: ---[ end trace 0000000000000000 ]--- RIP: 0010:generic_shutdown_super+0x290/0x2a0 Code: e8 15 7c f7 ff 48 8b 5d 28 48 89 df e8 09 7c f7 ff 48 8b 0b 48 89 ee 48 8d 95 68 06 00 00 48 c7 c7 80 7f db ac e8 00 69 af ff <0f> 0b 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 90 90 90 90 90 90 RSP: 0018:ffff88811cc27a50 EFLAGS: 00010246 RAX: 000000000000003e RBX: ffffffffae994420 RCX: 0000000000000027 RDX: 0000000000000000 RSI: ffffffffab06180e RDI: ffff8881f6eb18c8 RBP: ffff8881462ec000 R08: 0000000000000001 R09: ffffed103edd6319 R10: ffff8881f6eb18cb R11: 00000000016d3158 R12: ffff8881462ec9c0 R13: ffff8881462ec050 R14: 0000000000000001 R15: 0000000000000000 FS: 00007f23bfa98740(0000) GS:ffff8881f6e80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f8364005d68 CR3: 0000000123c80000 CR4: 0000000000350ef0
This reproduces eventually with an SMB mount and two shells running these loops concurrently
- while true; do
cd ~; sleep 1;
for i in {1..3}; do cd /mnt/test/subdir;
echo $PWD; sleep 1; cd ..; echo $PWD; sleep 1;
done;
echo ...;
done
- while true; do
iptables -F OUTPUT; mount -t cifs -a;
for _ in {0..2}; do ls /mnt/test/subdir/ | wc -l; done;
iptables -I OUTPUT -p tcp --dport 445 -j DROP;
sleep 10
echo "unmounting"; umount -l -t cifs -a; echo "done unmounting";
sleep 20
echo "recovering"; iptables -F OUTPUT;
sleep 10;done
--- fs/smb/client/cached_dir.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-)
fs/smb/client/cached_dir.c +14 -13
@@ -59,6 +59,16 @@ static struct cached_fid *find_or_createlist_add (&cfid->entry, &cfids->entries); cfid->on_list = true;kref_get (&cfid->refcount); +/* +* Set @cfid->has_lease to true during construction so that the lease +* reference can be put in cached_dir_lease_break() due to a potential +* lease break right after the request is sent or while @cfid is still +* being cached, or if a reconnection is triggered during construction. +* Concurrent processes won't be to use it yet due to @cfid->time being +* zero. +*/ + cfid->has_lease = true; +spin_unlock (&cfids->cfid_list_lock);return cfid; }
@@ -176,12 +186,12 @@ replay_again:return -ENOENT ; }/* -* Return cached fid if it has a lease. Otherwise, it is either a new -* entry or laundromat worker removed it from @cfids->entries. Caller -* will put last reference if the latter. +* Return cached fid if it is valid (has a lease and has a time). +* Otherwise, it is either a new entry or laundromat worker removed it +* from @cfids->entries. Caller will put last reference if the latter. */ spin_lock (&cfids->cfid_list_lock); -if (cfid->has_lease) { +if (cfid->has_lease && cfid->time) {spin_unlock (&cfids->cfid_list_lock); *ret_cfid = cfid;kfree (utf16_path);
@@ -267,15 +277,6 @@ replay_again:smb2_set_related (&rqst[1 ]); -/* -* Set @cfid->has_lease to true before sending out compounded request so -* its lease reference can be put in cached_dir_lease_break() due to a -* potential lease break right after the request is sent or while @cfid -* is still being cached. Concurrent processes won't be to use it yet -* due to @cfid->time being zero. -*/ - cfid->has_lease = true; -if (retries) {smb2_set_replay (server, &rqst[0 ]);smb2_set_replay (server, &rqst[1 ]);
Greg Kroah-Hartman
maintainerPATCH 543/676 smb: prevent use-after-free due to open_cached_dir error paths
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Aurich <[email protected]>
commit a9685b409a03b73d2980bbfa53eb47555802d0a9 upstream.
If open_cached_dir() encounters an error parsing the lease from the server, the error handling may race with receiving a lease break, resulting in open_cached_dir() freeing the cfid while the queued work is pending.
Update open_cached_dir() to drop refs rather than directly freeing the cfid.
Have cached_dir_lease_break(), cfids_laundromat_worker(), and invalidate_all_cached_dirs() clear has_lease immediately while still holding cfids->cfid_list_lock, and then use this to also simplify the reference counting in cfids_laundromat_worker() and invalidate_all_cached_dirs().
Fixes this KASAN splat (which manually injects an error and lease break in open_cached_dir()):
==================================================================
BUG: KASAN: slab-use-after-free in smb2_cached_lease_break+0x27/0xb0 Read of size 8 at addr ffff88811cc24c10 by task kworker/3:1/65 CPU: 3 UID: 0 PID: 65 Comm: kworker/3:1 Not tainted 6.12.0-rc6-g255cf264e6e5-dirty #87 Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 11/12/2020 Workqueue: cifsiod smb2_cached_lease_break Call Trace: <TASK> dump_stack_lvl+0x77/0xb0 print_report+0xce/0x660 kasan_report+0xd3/0x110 smb2_cached_lease_break+0x27/0xb0 process_one_work+0x50a/0xc50 worker_thread+0x2ba/0x530 kthread+0x17c/0x1c0 ret_from_fork+0x34/0x60 ret_from_fork_asm+0x1a/0x30 </TASK> Allocated by task 2464: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 __kasan_kmalloc+0xaa/0xb0 open_cached_dir+0xa7d/0x1fb0 smb2_query_path_info+0x43c/0x6e0 cifs_get_fattr+0x346/0xf10 cifs_get_inode_info+0x157/0x210 cifs_revalidate_dentry_attr+0x2d1/0x460 cifs_getattr+0x173/0x470 vfs_statx_path+0x10f/0x160 vfs_statx+0xe9/0x150 vfs_fstatat+0x5e/0xc0 __do_sys_newfstatat+0x91/0xf0 do_syscall_64+0x95/0x1a0 entry_SYSCALL_64_after_hwframe+0x76/0x7e Freed by task 2464: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 kasan_save_free_info+0x3b/0x60 __kasan_slab_free+0x51/0x70 kfree+0x174/0x520 open_cached_dir+0x97f/0x1fb0 smb2_query_path_info+0x43c/0x6e0 cifs_get_fattr+0x346/0xf10 cifs_get_inode_info+0x157/0x210 cifs_revalidate_dentry_attr+0x2d1/0x460 cifs_getattr+0x173/0x470 vfs_statx_path+0x10f/0x160 vfs_statx+0xe9/0x150 vfs_fstatat+0x5e/0xc0 __do_sys_newfstatat+0x91/0xf0 do_syscall_64+0x95/0x1a0 entry_SYSCALL_64_after_hwframe+0x76/0x7e Last potentially related work creation: kasan_save_stack+0x33/0x60 __kasan_record_aux_stack+0xad/0xc0 insert_work+0x32/0x100 __queue_work+0x5c9/0x870 queue_work_on+0x82/0x90 open_cached_dir+0x1369/0x1fb0 smb2_query_path_info+0x43c/0x6e0 cifs_get_fattr+0x346/0xf10 cifs_get_inode_info+0x157/0x210 cifs_revalidate_dentry_attr+0x2d1/0x460 cifs_getattr+0x173/0x470 vfs_statx_path+0x10f/0x160 vfs_statx+0xe9/0x150 vfs_fstatat+0x5e/0xc0 __do_sys_newfstatat+0x91/0xf0 do_syscall_64+0x95/0x1a0 entry_SYSCALL_64_after_hwframe+0x76/0x7e The buggy address belongs to the object at ffff88811cc24c00 which belongs to the cache kmalloc-1k of size 1024
The buggy address is located 16 bytes inside of
freed 1024-byte region [ffff88811cc24c00, ffff88811cc25000)
--- fs/smb/client/cached_dir.c | 70 ++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 41 deletions(-)
fs/smb/client/cached_dir.c +29 -41
@@ -348,6 +348,7 @@ oshr_free:SMB2_query_info_free (&rqst[1 ]);free_rsp_buf (resp_buftype[0 ], rsp_iov[0 ].iov_base);free_rsp_buf (resp_buftype[1 ], rsp_iov[1 ].iov_base); +out:if (rc) {spin_lock (&cfids->cfid_list_lock);if (cfid->on_list) {
@@ -359,23 +360,14 @@ oshr_free:/* * We are guaranteed to have two references at this * point. One for the caller and one for a potential -* lease. Release the Lease-ref so that the directory -* will be closed when the caller closes the cached -* handle. +* lease. Release one here, and the second below. */ cfid->has_lease = false; -spin_unlock (&cfids->cfid_list_lock);kref_put (&cfid->refcount, smb2_close_cached_fid); - goto out; }spin_unlock (&cfids->cfid_list_lock); - } -out: -if (rc) { -if (cfid->is_open) -SMB2_close (0 , cfid->tcon, cfid->fid.persistent_fid, - cfid->fid.volatile_fid); -free_cached_dir (cfid); + +kref_put (&cfid->refcount, smb2_close_cached_fid); }else { *ret_cfid = cfid;atomic_inc (&tcon->num_remote_opens);
@@ -513,25 +505,24 @@ void invalidate_all_cached_dirs(struct c cfids->num_entries--; cfid->is_open = false; cfid->on_list = false; -/* To prevent race with smb2_cached_lease_break() */ -kref_get (&cfid->refcount); +if (cfid->has_lease) { +/* +* The lease was never cancelled from the server, +* so steal that reference. +*/ + cfid->has_lease = false; + }else +kref_get (&cfid->refcount); }spin_unlock (&cfids->cfid_list_lock);list_for_each_entry_safe (cfid, q, &entry, entry) {list_del (&cfid->entry);cancel_work_sync (&cfid->lease_break); -if (cfid->has_lease) { -/* -* We lease was never cancelled from the server so we -* need to drop the reference. -*/ -spin_lock (&cfids->cfid_list_lock); - cfid->has_lease = false; -spin_unlock (&cfids->cfid_list_lock); -kref_put (&cfid->refcount, smb2_close_cached_fid); - } -/* Drop the extra reference opened above*/ +/* +* Drop the ref-count from above, either the lease-ref (if there +* was one) or the extra one acquired. +*/ kref_put (&cfid->refcount, smb2_close_cached_fid); } }
@@ -542,9 +533,6 @@ smb2_cached_lease_break(struct work_strustruct cached_fid *cfid =container_of (work, struct cached_fid, lease_break); -spin_lock (&cfid->cfids->cfid_list_lock); - cfid->has_lease = false; -spin_unlock (&cfid->cfids->cfid_list_lock);kref_put (&cfid->refcount, smb2_close_cached_fid); }
@@ -562,6 +550,7 @@ int cached_dir_lease_break(struct cifs_t !memcmp(lease_key, cfid->fid.lease_key, SMB2_LEASE_KEY_SIZE)) { + cfid->has_lease = false; cfid->time =0 ;/* * We found a lease remove it from the list
@@ -639,8 +628,14 @@ static void cfids_laundromat_worker(stru cfid->on_list = false;list_move (&cfid->entry, &entry); cfids->num_entries--; -/* To prevent race with smb2_cached_lease_break() */ -kref_get (&cfid->refcount); +if (cfid->has_lease) { +/* +* Our lease has not yet been cancelled from the +* server. Steal that reference. +*/ + cfid->has_lease = false; + }else +kref_get (&cfid->refcount); } }spin_unlock (&cfids->cfid_list_lock);
@@ -652,17 +647,10 @@ static void cfids_laundromat_worker(stru* with it. */ cancel_work_sync (&cfid->lease_break); -if (cfid->has_lease) { -/* -* Our lease has not yet been cancelled from the server -* so we need to drop the reference. -*/ -spin_lock (&cfids->cfid_list_lock); - cfid->has_lease = false; -spin_unlock (&cfids->cfid_list_lock); -kref_put (&cfid->refcount, smb2_close_cached_fid); - } -/* Drop the extra reference opened above */ +/* +* Drop the ref-count from above, either the lease-ref (if there +* was one) or the extra one acquired. +*/ kref_put (&cfid->refcount, smb2_close_cached_fid); } queue_delayed_work(cifsiod_wq, &cfids->laundromat_work,
Greg Kroah-Hartman
maintainerPATCH 544/676 smb: During unmount, ensure all cached dir instances drop their dentry
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Aurich <[email protected]>
commit 3fa640d035e5ae526769615c35cb9ed4be6e3662 upstream.
The unmount process (cifs_kill_sb() calling close_all_cached_dirs()) can race with various cached directory operations, which ultimately results in dentries not being dropped and these kernel BUGs:
BUG: Dentry ffff88814f37e358{i=1000000000080,n=/} still in use (2) [unmount of cifs cifs]
VFS: Busy inodes after unmount of cifs (cifs)
------------[ cut here ]------------
kernel BUG at fs/super.c:661!This happens when a cfid is in the process of being cleaned up when, and has been removed from the cfids->entries list, including:
- Receiving a lease break from the server
- Server reconnection triggers invalidate_all_cached_dirs(), which removes all the cfids from the list
- The laundromat thread decides to expire an old cfid.
To solve these problems, dropping the dentry is done in queued work done in a newly-added cfid_put_wq workqueue, and close_all_cached_dirs() flushes that workqueue after it drops all the dentries of which it's aware. This is a global workqueue (rather than scoped to a mount), but the queued work is minimal.
The final cleanup work for cleaning up a cfid is performed via work queued in the serverclose_wq workqueue; this is done separate from dropping the dentries so that close_all_cached_dirs() doesn't block on any server operations.
Both of these queued works expect to invoked with a cfid reference and a tcon reference to avoid those objects from being freed while the work is ongoing.
While we're here, add proper locking to close_all_cached_dirs(), and locking around the freeing of cfid->dentry.
--- fs/smb/client/cached_dir.c | 156 ++++++++++++++++++++++++++++++++++++--------- fs/smb/client/cached_dir.h | 6 + fs/smb/client/cifsfs.c | 12 +++ fs/smb/client/cifsglob.h | 3 fs/smb/client/inode.c | 3 fs/smb/client/trace.h | 3 6 files changed, 147 insertions(+), 36 deletions(-)
fs/smb/client/cached_dir.c +126 -30
@@ -17,6 +17,11 @@ static void free_cached_dir(struct cachestatic void smb2_close_cached_fid (struct kref *ref);static void cfids_laundromat_worker (struct work_struct *work); +struct cached_dir_dentry { +struct list_head entry; +struct dentry *dentry; +}; + static struct cached_fid *find_or_create_cached_dir(struct cached_fids *cfids, const char *path, bool lookup_only,
@@ -470,7 +475,10 @@ void close_all_cached_dirs(struct cifs_sstruct cifs_tcon *tcon;struct tcon_link *tlink;struct cached_fids *cfids; +struct cached_dir_dentry *tmp_list, *q; +LIST_HEAD (entry); +spin_lock (&cifs_sb->tlink_tree_lock);for (node =rb_first (root); node; node =rb_next (node)) { tlink = rb_entry(node, struct tcon_link, tl_rbnode); tcon =tlink_tcon (tlink);
@@ -479,11 +487,30 @@ void close_all_cached_dirs(struct cifs_s cfids = tcon->cfids;if (cfids ==NULL )continue ; +spin_lock (&cfids->cfid_list_lock);list_for_each_entry (cfid, &cfids->entries, entry) { -dput (cfid->dentry); + tmp_list =kmalloc (sizeof (*tmp_list),GFP_ATOMIC ); +if (tmp_list ==NULL ) +break ; +spin_lock (&cfid->fid_lock); + tmp_list->dentry = cfid->dentry; cfid->dentry =NULL ; +spin_unlock (&cfid->fid_lock); + +list_add_tail (&tmp_list->entry, &entry); } +spin_unlock (&cfids->cfid_list_lock); + } +spin_unlock (&cifs_sb->tlink_tree_lock); + +list_for_each_entry_safe (tmp_list, q, &entry, entry) { +list_del (&tmp_list->entry); +dput (tmp_list->dentry); +kfree (tmp_list); } + +/* Flush any pending work that will drop dentries */ +flush_workqueue (cfid_put_wq); }/*
@@ -494,14 +521,18 @@ void invalidate_all_cached_dirs(struct c {struct cached_fids *cfids = tcon->cfids;struct cached_fid *cfid, *q; -LIST_HEAD (entry);if (cfids ==NULL )return ; +/* +* Mark all the cfids as closed, and move them to the cfids->dying list. +* They'll be cleaned up later by cfids_invalidation_worker. Take +* a reference to each cfid during this process. +*/ spin_lock (&cfids->cfid_list_lock);list_for_each_entry_safe (cfid, q, &cfids->entries, entry) { -list_move (&cfid->entry, &entry); +list_move (&cfid->entry, &cfids->dying); cfids->num_entries--; cfid->is_open = false; cfid->on_list = false;
@@ -514,26 +545,47 @@ void invalidate_all_cached_dirs(struct c }else kref_get (&cfid->refcount); } +/* +* Queue dropping of the dentries once locks have been dropped +*/ +if (!list_empty (&cfids->dying)) +queue_work (cfid_put_wq, &cfids->invalidation_work);spin_unlock (&cfids->cfid_list_lock); - -list_for_each_entry_safe (cfid, q, &entry, entry) { -list_del (&cfid->entry); -cancel_work_sync (&cfid->lease_break); -/* -* Drop the ref-count from above, either the lease-ref (if there -* was one) or the extra one acquired. -*/ -kref_put (&cfid->refcount, smb2_close_cached_fid); - } }static void -smb2_cached_lease_break (struct work_struct *work) +cached_dir_offload_close (struct work_struct *work) {struct cached_fid *cfid =container_of (work, - struct cached_fid, lease_break); + struct cached_fid, close_work); +struct cifs_tcon *tcon = cfid->tcon; + +WARN_ON (cfid->on_list);kref_put (&cfid->refcount, smb2_close_cached_fid); +cifs_put_tcon (tcon, netfs_trace_tcon_ref_put_cached_close); +} + +/* +* Release the cached directory's dentry, and then queue work to drop cached +* directory itself (closing on server if needed). +* +* Must be called with a reference to the cached_fid and a reference to the +* tcon. +*/ +static void cached_dir_put_work (struct work_struct *work) +{ + struct cached_fid *cfid = container_of(work, struct cached_fid, + put_work); +struct dentry *dentry; + +spin_lock (&cfid->fid_lock); + dentry = cfid->dentry; + cfid->dentry =NULL ; +spin_unlock (&cfid->fid_lock); + +dput (dentry); +queue_work (serverclose_wq, &cfid->close_work); }int cached_dir_lease_break (struct cifs_tcon *tcon,__u8 lease_key[16 ])
@@ -560,8 +612,10 @@ int cached_dir_lease_break(struct cifs_t cfid->on_list = false; cfids->num_entries--; -queue_work (cifsiod_wq, - &cfid->lease_break); + ++tcon->tc_count; +trace_smb3_tcon_ref (tcon->debug_id, tcon->tc_count, + netfs_trace_tcon_ref_get_cached_lease_break); +queue_work (cfid_put_wq, &cfid->put_work);spin_unlock (&cfids->cfid_list_lock);return true; }
@@ -583,7 +637,8 @@ static struct cached_fid *init_cached_direturn NULL ; } -INIT_WORK (&cfid->lease_break, smb2_cached_lease_break); +INIT_WORK (&cfid->close_work, cached_dir_offload_close); +INIT_WORK (&cfid->put_work, cached_dir_put_work);INIT_LIST_HEAD (&cfid->entry);INIT_LIST_HEAD (&cfid->dirents.entries);mutex_init (&cfid->dirents.de_mutex);
@@ -596,6 +651,9 @@ static void free_cached_dir(struct cache {struct cached_dirent *dirent, *q; +WARN_ON (work_pending (&cfid->close_work)); +WARN_ON (work_pending (&cfid->put_work)); +dput (cfid->dentry); cfid->dentry =NULL ;
@@ -613,10 +671,30 @@ static void free_cached_dir(struct cachekfree (cfid); } +static void cfids_invalidation_worker (struct work_struct *work) +{ + struct cached_fids *cfids = container_of(work, struct cached_fids, + invalidation_work); +struct cached_fid *cfid, *q; +LIST_HEAD (entry); + +spin_lock (&cfids->cfid_list_lock); +/* move cfids->dying to the local list */ +list_cut_before (&entry, &cfids->dying, &cfids->dying); +spin_unlock (&cfids->cfid_list_lock); + +list_for_each_entry_safe (cfid, q, &entry, entry) { +list_del (&cfid->entry); +/* Drop the ref-count acquired in invalidate_all_cached_dirs */ +kref_put (&cfid->refcount, smb2_close_cached_fid); + } +} +static void cfids_laundromat_worker (struct work_struct *work) {struct cached_fids *cfids;struct cached_fid *cfid, *q; +struct dentry *dentry;LIST_HEAD (entry); cfids = container_of(work, struct cached_fids, laundromat_work.work);
@@ -642,18 +720,28 @@ static void cfids_laundromat_worker(strulist_for_each_entry_safe (cfid, q, &entry, entry) {list_del (&cfid->entry); -/* -* Cancel and wait for the work to finish in case we are racing -* with it. -*/ -cancel_work_sync (&cfid->lease_break); -/* -* Drop the ref-count from above, either the lease-ref (if there -* was one) or the extra one acquired. -*/ -kref_put (&cfid->refcount, smb2_close_cached_fid); + +spin_lock (&cfid->fid_lock); + dentry = cfid->dentry; + cfid->dentry =NULL ; +spin_unlock (&cfid->fid_lock); + +dput (dentry); +if (cfid->is_open) { +spin_lock (&cifs_tcp_ses_lock); + ++cfid->tcon->tc_count; +trace_smb3_tcon_ref (cfid->tcon->debug_id, cfid->tcon->tc_count, + netfs_trace_tcon_ref_get_cached_laundromat); +spin_unlock (&cifs_tcp_ses_lock); +queue_work (serverclose_wq, &cfid->close_work); + }else +/* +* Drop the ref-count from above, either the lease-ref (if there +* was one) or the extra one acquired. +*/ +kref_put (&cfid->refcount, smb2_close_cached_fid); } -queue_delayed_work (cifsiod_wq, &cfids->laundromat_work, +queue_delayed_work (cfid_put_wq, &cfids->laundromat_work, dir_cache_timeout *HZ ); }
@@ -666,9 +754,11 @@ struct cached_fids *init_cached_dirs(voireturn NULL ;spin_lock_init (&cfids->cfid_list_lock);INIT_LIST_HEAD (&cfids->entries); +INIT_LIST_HEAD (&cfids->dying); +INIT_WORK (&cfids->invalidation_work, cfids_invalidation_worker);INIT_DELAYED_WORK (&cfids->laundromat_work, cfids_laundromat_worker); -queue_delayed_work (cifsiod_wq, &cfids->laundromat_work, +queue_delayed_work (cfid_put_wq, &cfids->laundromat_work, dir_cache_timeout *HZ );return cfids;
@@ -687,12 +777,18 @@ void free_cached_dirs(struct cached_fidsreturn ;cancel_delayed_work_sync (&cfids->laundromat_work); +cancel_work_sync (&cfids->invalidation_work);spin_lock (&cfids->cfid_list_lock);list_for_each_entry_safe (cfid, q, &cfids->entries, entry) { cfid->on_list = false; cfid->is_open = false;list_move (&cfid->entry, &entry); + } +list_for_each_entry_safe (cfid, q, &cfids->dying, entry) { + cfid->on_list = false; + cfid->is_open = false; +list_move (&cfid->entry, &entry); }spin_unlock (&cfids->cfid_list_lock);
fs/smb/client/cached_dir.h +5 -1
@@ -44,7 +44,8 @@ struct cached_fid {spinlock_t fid_lock;struct cifs_tcon *tcon;struct dentry *dentry; -struct work_struct lease_break; +struct work_struct put_work; +struct work_struct close_work;struct smb2_file_all_info file_all_info;struct cached_dirents dirents; };
@@ -53,10 +54,13 @@ struct cached_fid {struct cached_fids {/* Must be held when: * - accessing the cfids->entries list +* - accessing the cfids->dying list */ spinlock_t cfid_list_lock;int num_entries;struct list_head entries; +struct list_head dying; +struct work_struct invalidation_work;struct delayed_work laundromat_work; };
fs/smb/client/cifsfs.c +11 -1
@@ -156,6 +156,7 @@ struct workqueue_struct *fileinfo_put_wqstruct workqueue_struct *cifsoplockd_wq;struct workqueue_struct *deferredclose_wq;struct workqueue_struct *serverclose_wq; +struct workqueue_struct *cfid_put_wq;__u32 cifs_lock_secret;/*
@@ -1899,9 +1900,16 @@ init_cifs(void) goto out_destroy_deferredclose_wq; } + cfid_put_wq =alloc_workqueue ("cfid_put_wq" , +WQ_FREEZABLE |WQ_MEM_RECLAIM ,0 ); +if (!cfid_put_wq) { + rc = -ENOMEM ; + goto out_destroy_serverclose_wq; + } + rc =cifs_init_inodecache ();if (rc) - goto out_destroy_serverclose_wq; + goto out_destroy_cfid_put_wq; rc =init_mids ();if (rc)
@@ -1963,6 +1971,8 @@ out_destroy_mids:destroy_mids (); out_destroy_inodecache:cifs_destroy_inodecache (); +out_destroy_cfid_put_wq: +destroy_workqueue (cfid_put_wq); out_destroy_serverclose_wq:destroy_workqueue (serverclose_wq); out_destroy_deferredclose_wq:
fs/smb/client/cifsglob.h +2 -1
@@ -2022,7 +2022,7 @@ require use of the stronger protocol */* cifsInodeInfo->lock_sem cifsInodeInfo->llist cifs_init_once * ->can_cache_brlcks * cifsInodeInfo->deferred_lock cifsInodeInfo->deferred_closes cifsInodeInfo_alloc -* cached_fid->fid_mutex cifs_tcon->crfid tcon_info_alloc +* cached_fids->cfid_list_lock cifs_tcon->cfids->entries init_cached_dirs * cifsFileInfo->fh_mutex cifsFileInfo cifs_new_fileinfo * cifsFileInfo->file_info_lock cifsFileInfo->count cifs_new_fileinfo * ->invalidHandle initiate_cifs_search
@@ -2111,6 +2111,7 @@ extern struct workqueue_struct *fileinfoextern struct workqueue_struct *cifsoplockd_wq;extern struct workqueue_struct *deferredclose_wq;extern struct workqueue_struct *serverclose_wq; +extern struct workqueue_struct *cfid_put_wq;extern __u32 cifs_lock_secret;extern mempool_t *cifs_sm_req_poolp;
fs/smb/client/inode.c +0 -3
@@ -2412,13 +2412,10 @@ cifs_dentry_needs_reval(struct dentry *dreturn true;if (!open_cached_dir_by_dentry (tcon, dentry->d_parent, &cfid)) { -spin_lock (&cfid->fid_lock);if (cfid->time && cifs_i->time > cfid->time) { -spin_unlock (&cfid->fid_lock);close_cached_dir (cfid);return false; } -spin_unlock (&cfid->fid_lock);close_cached_dir (cfid); }/*
fs/smb/client/trace.h +3 -0
@@ -27,6 +27,8 @@ EM(netfs_trace_tcon_ref_free_ipc, "FRE Ipc ") \ EM(netfs_trace_tcon_ref_free_ipc_fail, "FRE Ipc-F ") \ EM(netfs_trace_tcon_ref_free_reconnect_server, "FRE Reconn") \ + EM(netfs_trace_tcon_ref_get_cached_laundromat, "GET Ch-Lau") \ + EM(netfs_trace_tcon_ref_get_cached_lease_break, "GET Ch-Lea") \ EM(netfs_trace_tcon_ref_get_cancelled_close, "GET Cn-Cls") \ EM(netfs_trace_tcon_ref_get_dfs_refer, "GET DfsRef") \EM (netfs_trace_tcon_ref_get_find,"GET Find " ) \
@@ -35,6 +37,7 @@ EM(netfs_trace_tcon_ref_new, "NEW ") \ EM(netfs_trace_tcon_ref_new_ipc, "NEW Ipc ") \ EM(netfs_trace_tcon_ref_new_reconnect_server, "NEW Reconn") \ + EM(netfs_trace_tcon_ref_put_cached_close, "PUT Ch-Cls") \ EM(netfs_trace_tcon_ref_put_cancelled_close, "PUT Cn-Cls") \ EM(netfs_trace_tcon_ref_put_cancelled_close_fid, "PUT Cn-Fid") \EM (netfs_trace_tcon_ref_put_cancelled_mid,"PUT Cn-Mid" ) \
Greg Kroah-Hartman
maintainerPATCH 545/676 usb: musb: Fix hardware lockup on first Rx endpoint request
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hubert Wiśniewski <[email protected]>
commit 3fc137386c4620305bbc2a216868c53f9245670a upstream.
There is a possibility that a request's callback could be invoked from usb_ep_queue() (call trace below, supplemented with missing calls):
req->complete from usb_gadget_giveback_request
(drivers/usb/gadget/udc/core.c:999) usb_gadget_giveback_request from musb_g_giveback (drivers/usb/musb/musb_gadget.c:147) musb_g_giveback from rxstate (drivers/usb/musb/musb_gadget.c:784) rxstate from musb_ep_restart (drivers/usb/musb/musb_gadget.c:1169) musb_ep_restart from musb_ep_restart_resume_work (drivers/usb/musb/musb_gadget.c:1176) musb_ep_restart_resume_work from musb_queue_resume_work (drivers/usb/musb/musb_core.c:2279) musb_queue_resume_work from musb_gadget_queue (drivers/usb/musb/musb_gadget.c:1241) musb_gadget_queue from usb_ep_queue (drivers/usb/gadget/udc/core.c:300)
According to the docstring of usb_ep_queue(), this should not happen:
"Note that @req's ->complete() callback must never be called from within usb_ep_queue() as that can create deadlock situations."
In fact, a hardware lockup might occur in the following sequence:
1. The gadget is initialized using musb_gadget_enable().
2. Meanwhile, a packet arrives, and the RXPKTRDY flag is set, raising an interrupt.
3. If IRQs are enabled, the interrupt is handled, but musb_g_rx() finds an empty queue (next_request() returns NULL). The interrupt flag has already been cleared by the glue layer handler, but the RXPKTRDY flag remains set.
4. The first request is enqueued using usb_ep_queue(), leading to the call of req->complete(), as shown in the call trace above.
5. If the callback enables IRQs and another packet is waiting, step (3) repeats. The request queue is empty because usb_g_giveback() removes the request before invoking the callback.
6. The endpoint remains locked up, as the interrupt triggered by hardware setting the RXPKTRDY flag has been handled, but the flag itself remains set.
For this scenario to occur, it is only necessary for IRQs to be enabled at some point during the complete callback. This happens with the USB Ethernet gadget, whose rx_complete() callback calls netif_rx(). If called in the task context, netif_rx() disables the bottom halves (BHs). When the BHs are re-enabled, IRQs are also enabled to allow soft IRQs to be processed. The gadget itself is initialized at module load (or at boot if built-in), but the first request is enqueued when the network interface is brought up, triggering rx_complete() in the task context via ioctl(). If a packet arrives while the interface is down, it can prevent the interface from receiving any further packets from the USB host.
The situation is quite complicated with many parties involved. This particular issue can be resolved in several possible ways:
1. Ensure that callbacks never enable IRQs. This would be difficult to enforce, as discovering how netif_rx() interacts with interrupts was already quite challenging and u_ether is not the only function driver. Similar "bugs" could be hidden in other drivers as well.
2. Disable MUSB interrupts in musb_g_giveback() before calling the callback and re-enable them afterwars (by calling musb_{dis,en}able_interrupts(), for example). This would ensure that MUSB interrupts are not handled during the callback, even if IRQs are enabled. In fact, it would allow IRQs to be enabled when releasing the lock. However, this feels like an inelegant hack.
3. Modify the interrupt handler to clear the RXPKTRDY flag if the request queue is empty. While this approach also feels like a hack, it wastes CPU time by attempting to handle incoming packets when the software is not ready to process them.
4. Flush the Rx FIFO instead of calling rxstate() in musb_ep_restart(). This ensures that the hardware can receive packets when there is at least one request in the queue. Once IRQs are enabled, the interrupt handler will be able to correctly process the next incoming packet (eventually calling rxstate()). This approach may cause one or two packets to be dropped (two if double buffering is enabled), but this seems to be a minor issue, as packet loss can occur when the software is not yet ready to process them. Additionally, this solution makes the gadget driver compliant with the rule mentioned in the docstring of usb_ep_queue().
There may be additional solutions, but from these four, the last one has been chosen as it seems to be the most appropriate, as it addresses the "bad" behavior of the driver.
--- drivers/usb/musb/musb_gadget.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
drivers/usb/musb/musb_gadget.c +10 -3
@@ -1170,12 +1170,19 @@ struct free_record {*/ void musb_ep_restart (struct musb *musb,struct musb_request *req) { +u16 csr; +void __iomem *epio = req->ep->hw_ep->regs; +trace_musb_req_start (req);musb_ep_select (musb->mregs, req->epnum); -if (req->tx) +if (req->tx) {txstate (musb, req); -else -rxstate (musb, req); + }else { + csr =musb_readw (epio,MUSB_RXCSR ); + csr |=MUSB_RXCSR_FLUSHFIFO |MUSB_RXCSR_P_WZC_BITS ; +musb_writew (epio,MUSB_RXCSR , csr); +musb_writew (epio,MUSB_RXCSR , csr); + } }static int musb_ep_restart_resume_work (struct musb *musb,void *data)
Greg Kroah-Hartman
maintainerPATCH 546/676 usb: dwc3: gadget: Fix checking for number of TRBs left
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thinh Nguyen <[email protected]>
commit 02a6982b0ccfcdc39e20016f5fc9a1b7826a6ee7 upstream.
The check whether the TRB ring is full or empty in dwc3_calc_trbs_left() is insufficient. It assumes there are active TRBs if there's any request in the started_list. However, that's not the case for requests with a large SG list.
That is, if we have a single usb request that requires more TRBs than the total TRBs in the TRB ring, the queued TRBs will be available when all the TRBs in the ring are completed. But the request is only partially completed and remains in the started_list. With the current logic, the TRB ring is empty, but dwc3_calc_trbs_left() returns 0.
Fix this by additionally checking for the request->num_trbs for active TRB count.
--- drivers/usb/dwc3/gadget.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/usb/dwc3/gadget.c +6 -3
@@ -1196,11 +1196,14 @@ static u32 dwc3_calc_trbs_left(struct dw* pending to be processed by the driver. */ if (dep->trb_enqueue == dep->trb_dequeue) { +struct dwc3_request *req; +/* -* If there is any request remained in the started_list at -* this point, that means there is no TRB available. +* If there is any request remained in the started_list with +* active TRBs at this point, then there is no TRB available. */ -if (!list_empty (&dep->started_list)) + req =next_request (&dep->started_list); +if (req && req->num_trbs)return 0 ;return DWC3_TRB_NUM -1 ;
Greg Kroah-Hartman
maintainerPATCH 547/676 usb: dwc3: gadget: Fix looping of queued SG entries
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thinh Nguyen <[email protected]>
commit b7fc65f5141c24785dc8c19249ca4efcf71b3524 upstream.
The dwc3_request->num_queued_sgs is decremented on completion. If a partially completed request is handled, then the dwc3_request->num_queued_sgs no longer reflects the total number of num_queued_sgs (it would be cleared).
Correctly check the number of request SG entries remained to be prepare and queued. Failure to do this may cause null pointer dereference when accessing non-existent SG entry.
--- drivers/usb/dwc3/gadget.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/usb/dwc3/gadget.c +3 -3
@@ -1436,8 +1436,8 @@ static int dwc3_prepare_trbs_sg(struct dstruct scatterlist *s;int i;unsigned int length = req->request.length; -unsigned int remaining = req->request.num_mapped_sgs - - req->num_queued_sgs; +unsigned int remaining = req->num_pending_sgs; +unsigned int num_queued_sgs = req->request.num_mapped_sgs - remaining;unsigned int num_trbs = req->num_trbs;bool needs_extra_trb =dwc3_needs_extra_trb (dep, req);
@@ -1445,7 +1445,7 @@ static int dwc3_prepare_trbs_sg(struct d* If we resume preparing the request, then get the remaining length of * the request and resume where we left off. */ -for_each_sg (req->request.sg, s, req->num_queued_sgs, i) +for_each_sg (req->request.sg, s, num_queued_sgs, i) length -=sg_dma_len (s);for_each_sg (sg, s, remaining, i) {
Greg Kroah-Hartman
maintainerPATCH 548/676 ublk: fix error code for unsupported command
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Lei <[email protected]>
commit 34c1227035b3ab930a1ae6ab6f22fec1af8ab09e upstream.
ENOTSUPP is for kernel use only, and shouldn't be sent to userspace.
Fix it by replacing it with EOPNOTSUPP.
--- drivers/block/ublk_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/block/ublk_drv.c +1 -1
@@ -2913,7 +2913,7 @@ static int ublk_ctrl_uring_cmd(struct io ret =ublk_ctrl_end_recovery (ub, cmd);break ;default : - ret = -ENOTSUPP ; + ret = -EOPNOTSUPP ;break ; }
Greg Kroah-Hartman
maintainerPATCH 549/676 lib: string_helpers: silence snprintf() output truncation warning
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bartosz Golaszewski <[email protected]>
commit a508ef4b1dcc82227edc594ffae583874dd425d7 upstream.
The output of ".%03u" with the unsigned int in range [0, 4294966295] may get truncated if the target buffer is not 12 bytes. This can't really happen here as the 'remainder' variable cannot exceed 999 but the compiler doesn't know it. To make it happy just increase the buffer to where the warning goes away.
--- lib/string_helpers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
lib/string_helpers.c +1 -1
@@ -52,7 +52,7 @@ void string_get_size(u64 size, u64 blk_sstatic const unsigned int rounding[] = {500 ,50 ,5 };int i =0 , j;u32 remainder =0 , sf_cap; -char tmp[8 ]; +char tmp[12 ];const char *unit; tmp[0 ] ='\0' ;
Greg Kroah-Hartman
maintainerPATCH 550/676 f2fs: fix to do sanity check on node blkaddr in truncate_node()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
commit 6babe00ccd34fc65b78ef8b99754e32b4385f23d upstream.
syzbot reports a f2fs bug as below:
------------[ cut here ]------------ kernel BUG at fs/f2fs/segment.c:2534! RIP: 0010:f2fs_invalidate_blocks+0x35f/0x370 fs/f2fs/segment.c:2534 Call Trace: truncate_node+0x1ae/0x8c0 fs/f2fs/node.c:909 f2fs_remove_inode_page+0x5c2/0x870 fs/f2fs/node.c:1288 f2fs_evict_inode+0x879/0x15c0 fs/f2fs/inode.c:856 evict+0x4e8/0x9b0 fs/inode.c:723 f2fs_handle_failed_inode+0x271/0x2e0 fs/f2fs/inode.c:986 f2fs_create+0x357/0x530 fs/f2fs/namei.c:394 lookup_open fs/namei.c:3595 [inline] open_last_lookups fs/namei.c:3694 [inline] path_openat+0x1c03/0x3590 fs/namei.c:3930 do_filp_open+0x235/0x490 fs/namei.c:3960 do_sys_openat2+0x13e/0x1d0 fs/open.c:1415 do_sys_open fs/open.c:1430 [inline] __do_sys_openat fs/open.c:1446 [inline] __se_sys_openat fs/open.c:1441 [inline] __x64_sys_openat+0x247/0x2a0 fs/open.c:1441 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0010:f2fs_invalidate_blocks+0x35f/0x370 fs/f2fs/segment.c:2534
The root cause is: on a fuzzed image, blkaddr in nat entry may be corrupted, then it will cause system panic when using it in f2fs_invalidate_blocks(), to avoid this, let's add sanity check on nat blkaddr in truncate_node().
--- fs/f2fs/node.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
fs/f2fs/node.c +10 -0
@@ -905,6 +905,16 @@ static int truncate_node(struct dnode_ofif (err)return err; +if (ni.blk_addr !=NEW_ADDR && + !f2fs_is_valid_blkaddr (sbi, ni.blk_addr,DATA_GENERIC_ENHANCE )) { +f2fs_err_ratelimited (sbi, +"nat entry is corrupted, run fsck to fix it, ino:%u, " +"nid:%u, blkaddr:%u" , ni.ino, ni.nid, ni.blk_addr); +set_sbi_flag (sbi,SBI_NEED_FSCK ); +f2fs_handle_error (sbi,ERROR_INCONSISTENT_NAT ); +return -EFSCORRUPTED ; + } +/* Deallocate node address */ f2fs_invalidate_blocks (sbi, ni.blk_addr);dec_valid_node_count (sbi, dn->inode, dn->nid == dn->inode->i_ino);
Greg Kroah-Hartman
maintainerPATCH 551/676 ipc: fix memleak if msg_init_ns failed in create_ipc_ns
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Wupeng <[email protected]>
commit bc8f5921cd69188627c08041276238de222ab466 upstream.
Percpu memory allocation may failed during create_ipc_ns however this fail is not handled properly since ipc sysctls and mq sysctls is not released properly. Fix this by release these two resource when failure.
Here is the kmemleak stack when percpu failed:
unreferenced object 0xffff88819de2a600 (size 512):
comm "shmem_2nstest", pid 120711, jiffies 4300542254 hex dump (first 32 bytes):
60 aa 9d 84 ff ff ff ff fc 18 48 b2 84 88 ff ff `.........H.....
04 00 00 00 a4 01 00 00 20 e4 56 81 ff ff ff ff ........ .V.....
backtrace (crc be7cba35):
[<ffffffff81b43f83>] __kmalloc_node_track_caller_noprof+0x333/0x420
[<ffffffff81a52e56>] kmemdup_noprof+0x26/0x50
[<ffffffff821b2f37>] setup_mq_sysctls+0x57/0x1d0
[<ffffffff821b29cc>] copy_ipcs+0x29c/0x3b0
[<ffffffff815d6a10>] create_new_namespaces+0x1d0/0x920
[<ffffffff815d7449>] copy_namespaces+0x2e9/0x3e0
[<ffffffff815458f3>] copy_process+0x29f3/0x7ff0
[<ffffffff8154b080>] kernel_clone+0xc0/0x650
[<ffffffff8154b6b1>] __do_sys_clone+0xa1/0xe0
[<ffffffff843df8ff>] do_syscall_64+0xbf/0x1c0
[<ffffffff846000b0>] entry_SYSCALL_64_after_hwframe+0x4b/0x53--- ipc/namespace.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
ipc/namespace.c +3 -1
@@ -83,13 +83,15 @@ static struct ipc_namespace *create_ipc_ err =msg_init_ns (ns);if (err) - goto fail_put; + goto fail_ipc;sem_init_ns (ns);shm_init_ns (ns);return ns; +fail_ipc: +retire_ipc_sysctls (ns); fail_mq:retire_mq_sysctls (ns);
Greg Kroah-Hartman
maintainerPATCH 552/676 NFSD: Prevent a potential integer overflow
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
commit 7f33b92e5b18e904a481e6e208486da43e4dc841 upstream.
If the tag length is >= U32_MAX - 3 then the "length + 4" addition can result in an integer overflow. Address this by splitting the decoding into several steps so that decode_cb_compound4res() does not have to perform arithmetic on the unsafe length value.
--- fs/nfsd/nfs4callback.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
fs/nfsd/nfs4callback.c +7 -7
@@ -297,17 +297,17 @@ static int decode_cb_compound4res(structu32 length;__be32 *p; - p =xdr_inline_decode (xdr,4 +4 ); + p =xdr_inline_decode (xdr,XDR_UNIT );if (unlikely (p ==NULL )) goto out_overflow; - hdr->status =be32_to_cpup (p++); + hdr->status =be32_to_cpup (p);/* Ignore the tag */ - length =be32_to_cpup (p++); - p =xdr_inline_decode (xdr, length +4 ); -if (unlikely (p ==NULL )) +if (xdr_stream_decode_u32 (xdr, &length) <0 ) + goto out_overflow; +if (xdr_inline_decode (xdr, length) ==NULL ) + goto out_overflow; +if (xdr_stream_decode_u32 (xdr, &hdr->nops) <0 ) goto out_overflow; - p +=XDR_QUADLEN (length); - hdr->nops =be32_to_cpup (p);return 0 ; out_overflow:return -EIO ;
Greg Kroah-Hartman
maintainerPATCH 553/676 SUNRPC: make sure cache entry active before cache_show
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Erkun <[email protected]>
commit 2862eee078a4d2d1f584e7f24fa50dddfa5f3471 upstream.
The function c_show was called with protection from RCU. This only ensures that cp will not be freed. Therefore, the reference count for cp can drop to zero, which will trigger a refcount use-after-free warning when cache_get is called. To resolve this issue, use cache_get_rcu to ensure that cp remains active.
------------[ cut here ]------------ refcount_t: addition on 0; use-after-free. WARNING: CPU: 7 PID: 822 at lib/refcount.c:25 refcount_warn_saturate+0xb1/0x120 CPU: 7 UID: 0 PID: 822 Comm: cat Not tainted 6.12.0-rc3+ #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.1-2.fc37 04/01/2014 RIP: 0010:refcount_warn_saturate+0xb1/0x120 Call Trace: <TASK> c_show+0x2fc/0x380 [sunrpc] seq_read_iter+0x589/0x770 seq_read+0x1e5/0x270 proc_reg_read+0xe1/0x140 vfs_read+0x125/0x530 ksys_read+0xc1/0x160 do_syscall_64+0x5f/0x170 entry_SYSCALL_64_after_hwframe+0x76/0x7e
--- net/sunrpc/cache.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/sunrpc/cache.c +3 -1
@@ -1431,7 +1431,9 @@ static int c_show(struct seq_file *m, voseq_printf (m,"# expiry=%lld refcnt=%d flags=%lx\n" ,convert_to_wallclock (cp->expiry_time),kref_read (&cp->ref), cp->flags); -cache_get (cp); +if (!cache_get_rcu (cp)) +return 0 ; +if (cache_check (cd, cp,NULL ))/* cache_check does a cache_put on failure */ seq_puts (m,"# " );
Greg Kroah-Hartman
maintainerPATCH 554/676 um: Fix potential integer overflow during physmem setup
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tiwei Bie <[email protected]>
[ Upstream commit a98b7761f697e590ed5d610d87fa12be66f23419 ]
This issue happens when the real map size is greater than LONG_MAX, which can be easily triggered on UML/i386.
--- arch/um/kernel/physmem.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/um/kernel/physmem.c +3 -3
@@ -80,10 +80,10 @@ void __init setup_physmem(unsigned long start, unsigned long reserve_end, unsigned long len, unsigned long long highmem) {unsigned long reserve = reserve_end - start; -long map_size = len - reserve; +unsigned long map_size = len - reserve;int err; -if (map_size <=0 ) { +if (len <= reserve) {os_warn ("Too few physical memory! Needed=%lu, given=%lu\n" , reserve, len);exit (1 );
@@ -94,7 +94,7 @@ void __init setup_physmem(unsigned long start, unsigned long reserve_end, err =os_map_memory ((void *) reserve_end, physmem_fd, reserve, map_size,1 ,1 ,1 );if (err <0 ) { -os_warn ("setup_physmem - mapping %ld bytes of memory at 0x%p " +os_warn ("setup_physmem - mapping %lu bytes of memory at 0x%p " "failed - errno = %d\n" , map_size, (void *) reserve_end, err);exit (1 );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 555/676 um: Fix the return value of elf_core_copy_task_fpregs
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tiwei Bie <[email protected]>
[ Upstream commit 865e3845eeaa21e9a62abc1361644e67124f1ec0 ]
This function is expected to return a boolean value, which should be true on success and false on failure.
--- arch/um/kernel/process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/um/kernel/process.c +1 -1
@@ -397,6 +397,6 @@ int elf_core_copy_task_fpregs(struct task_struct *t, elf_fpregset_t *fpu) {int cpu =current_thread_info ()->cpu; -return save_i387_registers (userspace_pid[cpu], (unsigned long *) fpu); +return save_i387_registers (userspace_pid[cpu], (unsigned long *) fpu) ==0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 556/676 um: Always dump trace for specified task in show_stack
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tiwei Bie <[email protected]>
[ Upstream commit 0f659ff362eac69777c4c191b7e5ccb19d76c67d ]
Currently, show_stack() always dumps the trace of the current task. However, it should dump the trace of the specified task if one is provided. Otherwise, things like running "echo t > sysrq-trigger" won't work as expected.
--- arch/um/kernel/sysrq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/um/kernel/sysrq.c +1 -1
@@ -53,5 +53,5 @@ void show_stack(struct task_struct *task, unsigned long *stack, }printk ("%sCall Trace:\n" , loglvl); -dump_trace (current, &stackops, (void *)loglvl); +dump_trace (task ?: current, &stackops, (void *)loglvl); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 557/676 NFSv4.0: Fix a use-after-free problem in the asynchronous open()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
[ Upstream commit 2fdb05dc0931250574f0cb0ebeb5ed8e20f4a889 ]
Yang Erkun reports that when two threads are opening files at the same time, and are forced to abort before a reply is seen, then the call to nfs_release_seqid() in nfs4_opendata_free() can result in a use-after-free of the pointer to the defunct rpc task of the other thread.
The fix is to ensure that if the RPC call is aborted before the call to nfs_wait_on_sequence() is complete, then we must call nfs_release_seqid() in nfs4_open_release() before the rpc_task is freed.
--- fs/nfs/nfs4proc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
fs/nfs/nfs4proc.c +5 -3
@@ -2528,12 +2528,14 @@ static void nfs4_open_release(void *calldata)struct nfs4_opendata *data = calldata;struct nfs4_state *state =NULL ; +/* In case of error, no cleanup! */ +if (data->rpc_status !=0 || !data->rpc_done) { +nfs_release_seqid (data->o_arg.seqid); + goto out_free; + }/* If this request hasn't been cancelled, do nothing */ if (!data->cancelled) goto out_free; -/* In case of error, no cleanup! */ -if (data->rpc_status !=0 || !data->rpc_done) - goto out_free;/* In case we need an open_confirm, no cleanup! */ if (data->o_res.rflags &NFS4_OPEN_RESULT_CONFIRM ) goto out_free;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 558/676 rtc: st-lpc: Use IRQF_NO_AUTOEN flag in request_irq()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit b6cd7adec0cf03f0aefc55676e71dd721cbc71a8 ]
If request_irq() fails in st_rtc_probe(), there is no need to enable the irq, and if it succeeds, disable_irq() after request_irq() still has a time gap in which interrupts can come.
request_irq() with IRQF_NO_AUTOEN flag will disable IRQ auto-enable when request IRQ.
--- drivers/rtc/rtc-st-lpc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/rtc/rtc-st-lpc.c +2 -3
@@ -218,15 +218,14 @@ static int st_rtc_probe(struct platform_device *pdev)return -EINVAL ; } - ret =devm_request_irq (&pdev->dev, rtc->irq, st_rtc_handler,0 , - pdev->name, rtc); + ret =devm_request_irq (&pdev->dev, rtc->irq, st_rtc_handler, +IRQF_NO_AUTOEN , pdev->name, rtc);if (ret) {dev_err (&pdev->dev,"Failed to request irq %i\n" , rtc->irq);return ret; }enable_irq_wake (rtc->irq); -disable_irq (rtc->irq); rtc->clk =devm_clk_get_enabled (&pdev->dev,NULL );if (IS_ERR (rtc->clk))
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 559/676 rtc: abx80x: Fix WDT bit position of the status register
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nobuhiro Iwamatsu <[email protected]>
[ Upstream commit 10e078b273ee7a2b8b4f05a64ac458f5e652d18d ]
The WDT bit in the status register is 5, not 6. This fixes from 6 to 5.
--- drivers/rtc/rtc-abx80x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/rtc/rtc-abx80x.c +1 -1
@@ -39,7 +39,7 @@#define ABX8XX_REG_STATUS 0x0f#define ABX8XX_STATUS_AF BIT(2)#define ABX8XX_STATUS_BLF BIT(4) -#define ABX8XX_STATUS_WDT BIT(6) +#define ABX8XX_STATUS_WDT BIT(5)#define ABX8XX_REG_CTRL1 0x10#define ABX8XX_CTRL_WRITE BIT(0)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 560/676 rtc: check if __rtc_read_time was successful in rtc_timer_do_work()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yongliang Gao <[email protected]>
[ Upstream commit e8ba8a2bc4f60a1065f23d6a0e7cbea945a0f40d ]
If the __rtc_read_time call fails,, the struct rtc_time tm; may contain uninitialized data, or an illegal date/time read from the RTC hardware.
When calling rtc_tm_to_ktime later, the result may be a very large value (possibly KTIME_MAX). If there are periodic timers in rtc->timerqueue, they will continually expire, may causing kernel softlockup.
--- drivers/rtc/interface.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/rtc/interface.c +6 -1
@@ -904,13 +904,18 @@ void rtc_timer_do_work(struct work_struct *work)struct timerqueue_node *next;ktime_t now;struct rtc_time tm; +int err;struct rtc_device *rtc = container_of(work, struct rtc_device, irqwork);mutex_lock (&rtc->ops_lock); again: -__rtc_read_time (rtc, &tm); + err =__rtc_read_time (rtc, &tm); +if (err) { +mutex_unlock (&rtc->ops_lock); +return ; + } now =rtc_tm_to_ktime (tm);while ((next =timerqueue_getnext (&rtc->timerqueue))) {if (next->expires > now)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 561/676 ubi: fastmap: wl: Schedule fm_work if wear-leveling pool is empty
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhihao Cheng <[email protected]>
[ Upstream commit c4595fe394a289927077e3da561db27811919ee0 ]
Since commit 14072ee33d5a ("ubi: fastmap: Check wl_pool for free peb before wear leveling"), wear_leveling_worker() won't schedule fm_work if wear-leveling pool is empty, which could temporarily disable the wear-leveling until the fastmap is updated(eg. pool becomes empty). Fix it by scheduling fm_work if wl_pool is empty during wear-leveing.
--- drivers/mtd/ubi/fastmap-wl.c | 19 ++++++++++++++++--- drivers/mtd/ubi/wl.c | 2 +- drivers/mtd/ubi/wl.h | 3 ++- 3 files changed, 19 insertions(+), 5 deletions(-)
drivers/mtd/ubi/fastmap-wl.c +16 -3
@@ -282,14 +282,27 @@ int ubi_wl_get_peb(struct ubi_device *ubi)* WL sub-system. * * @ubi: UBI device description object +* @need_fill: whether to fill wear-leveling pool when no PEBs are found */ -static struct ubi_wl_entry *next_peb_for_wl (struct ubi_device *ubi) +static struct ubi_wl_entry *next_peb_for_wl (struct ubi_device *ubi, +bool need_fill) {struct ubi_fm_pool *pool = &ubi->fm_wl_pool;int pnum; -if (pool->used == pool->size) +if (pool->used == pool->size) { +if (need_fill && !ubi->fm_work_scheduled) { +/* +* We cannot update the fastmap here because this +* function is called in atomic context. +* Let's fail here and refill/update it as soon as +* possible. +*/ + ubi->fm_work_scheduled =1 ; +schedule_work (&ubi->fm_work); + }return NULL ; + } pnum = pool->pebs[pool->used];return ubi->lookuptbl[pnum];
@@ -311,7 +324,7 @@ static bool need_wear_leveling(struct ubi_device *ubi)if (!ubi->used.rb_node)return false; - e =next_peb_for_wl (ubi); + e =next_peb_for_wl (ubi, false);if (!e) {if (!ubi->free.rb_node)return false;
drivers/mtd/ubi/wl.c +1 -1
@@ -671,7 +671,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,ubi_assert (!ubi->move_to_put);#ifdef CONFIG_MTD_UBI_FASTMAP - if (!next_peb_for_wl(ubi) || + if (!next_peb_for_wl(ubi, true) || #else if (!ubi->free.rb_node ||#endif
drivers/mtd/ubi/wl.h +2 -1
@@ -5,7 +5,8 @@static void update_fastmap_work_fn (struct work_struct *wrk);static struct ubi_wl_entry *find_anchor_wl_entry (struct rb_root *root);static struct ubi_wl_entry *get_peb_for_wl (struct ubi_device *ubi); -static struct ubi_wl_entry *next_peb_for_wl (struct ubi_device *ubi); +static struct ubi_wl_entry *next_peb_for_wl (struct ubi_device *ubi, +bool need_fill);static bool need_wear_leveling (struct ubi_device *ubi);static void ubi_fastmap_close (struct ubi_device *ubi);static inline void ubi_fastmap_init (struct ubi_device *ubi,int *count)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 562/676 ubifs: Correct the total block count by deducting journal reservation
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhihao Cheng <[email protected]>
[ Upstream commit 84a2bee9c49769310efa19601157ef50a1df1267 ]
Since commit e874dcde1cbf ("ubifs: Reserve one leb for each journal head while doing budget"), available space is calulated by deducting reservation for all journal heads. However, the total block count ( which is only used by statfs) is not updated yet, which will cause the wrong displaying for used space(total - available). Fix it by deducting reservation for all journal heads from total block count.
--- fs/ubifs/super.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
fs/ubifs/super.c +3 -3
@@ -777,10 +777,10 @@ static void init_constants_master(struct ubifs_info *c)* necessary to report something for the 'statfs()' call. * * Subtract the LEB reserved for GC, the LEB which is reserved for -* deletions, minimum LEBs for the index, and assume only one journal -* head is available. +* deletions, minimum LEBs for the index, the LEBs which are reserved +* for each journal head. */ - tmp64 = c->main_lebs -1 -1 -MIN_INDEX_LEBS - c->jhead_cnt +1 ; + tmp64 = c->main_lebs -1 -1 -MIN_INDEX_LEBS - c->jhead_cnt; tmp64 *= (long long )c->leb_size - c->leb_overhead; tmp64 =ubifs_reported_space (c, tmp64); c->block_cnt = tmp64 >>UBIFS_BLOCK_SHIFT ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 563/676 ubi: fastmap: Fix duplicate slab cache names while attaching
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhihao Cheng <[email protected]>
[ Upstream commit bcddf52b7a17adcebc768d26f4e27cf79adb424c ]
Since commit 4c39529663b9 ("slab: Warn on duplicate cache names when DEBUG_VM=y"), the duplicate slab cache names can be detected and a kernel WARNING is thrown out.
In UBI fast attaching process, alloc_ai() could be invoked twice with the same slab cache name 'ubi_aeb_slab_cache', which will trigger following warning messages:
kmem_cache of name 'ubi_aeb_slab_cache' already exists
WARNING: CPU: 0 PID: 7519 at mm/slab_common.c:107
__kmem_cache_create_args+0x100/0x5f0
Modules linked in: ubi(+) nandsim [last unloaded: nandsim]
CPU: 0 UID: 0 PID: 7519 Comm: modprobe Tainted: G 6.12.0-rc2
RIP: 0010:__kmem_cache_create_args+0x100/0x5f0
Call Trace:
__kmem_cache_create_args+0x100/0x5f0
alloc_ai+0x295/0x3f0 [ubi]
ubi_attach+0x3c3/0xcc0 [ubi]
ubi_attach_mtd_dev+0x17cf/0x3fa0 [ubi]
ubi_init+0x3fb/0x800 [ubi]
do_init_module+0x265/0x7d0
__x64_sys_finit_module+0x7a/0xc0The problem could be easily reproduced by loading UBI device by fastmap with CONFIG_DEBUG_VM=y.
Fix it by using different slab names for alloc_ai() callers.
--- drivers/mtd/ubi/attach.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/mtd/ubi/attach.c +6 -6
@@ -1447,7 +1447,7 @@ static int scan_all(struct ubi_device *ubi, struct ubi_attach_info *ai,return err; } -static struct ubi_attach_info *alloc_ai (void ) +static struct ubi_attach_info *alloc_ai (const char *slab_name) {struct ubi_attach_info *ai;
@@ -1461,7 +1461,7 @@ static struct ubi_attach_info *alloc_ai(void)INIT_LIST_HEAD (&ai->alien);INIT_LIST_HEAD (&ai->fastmap); ai->volumes =RB_ROOT ; - ai->aeb_slab_cache =kmem_cache_create ("ubi_aeb_slab_cache" , + ai->aeb_slab_cache =kmem_cache_create (slab_name,sizeof (struct ubi_ainf_peb ),0 ,0 ,NULL );if (!ai->aeb_slab_cache) {
@@ -1491,7 +1491,7 @@ static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info **ai) err = -ENOMEM ; - scan_ai =alloc_ai (); + scan_ai =alloc_ai ("ubi_aeb_slab_cache_fastmap" );if (!scan_ai) goto out;
@@ -1557,7 +1557,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan)int err;struct ubi_attach_info *ai; - ai =alloc_ai (); + ai =alloc_ai ("ubi_aeb_slab_cache" );if (!ai)return -ENOMEM ;
@@ -1575,7 +1575,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan)if (err >0 ||mtd_is_eccerr (err)) {if (err !=UBI_NO_FASTMAP ) {destroy_ai (ai); - ai =alloc_ai (); + ai =alloc_ai ("ubi_aeb_slab_cache" );if (!ai)return -ENOMEM ;
@@ -1614,7 +1614,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan)if (ubi->fm &&ubi_dbg_chk_fastmap (ubi)) {struct ubi_attach_info *scan_ai; - scan_ai =alloc_ai (); + scan_ai =alloc_ai ("ubi_aeb_slab_cache_dbg_chk_fastmap" );if (!scan_ai) { err = -ENOMEM ; goto out_wl;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 564/676 ubifs: authentication: Fix use-after-free in ubifs_tnc_end_commit
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Waqar Hameed <[email protected]>
[ Upstream commit 4617fb8fc15effe8eda4dd898d4e33eb537a7140 ]
After an insertion in TNC, the tree might split and cause a node to change its znode->parent. A further deletion of other nodes in the tree (which also could free the nodes), the aforementioned node's znode->cparent could still point to a freed node. This znode->cparent may not be updated when getting nodes to commit in ubifs_tnc_start_commit(). This could then trigger a use-after-free when accessing the znode->cparent in write_index() in ubifs_tnc_end_commit().
This can be triggered by running
rm -f /etc/test-file.bin
dd if=/dev/urandom of=/etc/test-file.bin bs=1M count=60 conv=fsync
in a loop, and with CONFIG_UBIFS_FS_AUTHENTICATION. KASAN then reports:
BUG: KASAN: use-after-free in ubifs_tnc_end_commit+0xa5c/0x1950 Write of size 32 at addr ffffff800a3af86c by task ubifs_bgt0_20/153 Call trace: dump_backtrace+0x0/0x340 show_stack+0x18/0x24 dump_stack_lvl+0x9c/0xbc print_address_description.constprop.0+0x74/0x2b0 kasan_report+0x1d8/0x1f0 kasan_check_range+0xf8/0x1a0 memcpy+0x84/0xf4 ubifs_tnc_end_commit+0xa5c/0x1950 do_commit+0x4e0/0x1340 ubifs_bg_thread+0x234/0x2e0 kthread+0x36c/0x410 ret_from_fork+0x10/0x20 Allocated by task 401: kasan_save_stack+0x38/0x70 __kasan_kmalloc+0x8c/0xd0 __kmalloc+0x34c/0x5bc tnc_insert+0x140/0x16a4 ubifs_tnc_add+0x370/0x52c ubifs_jnl_write_data+0x5d8/0x870 do_writepage+0x36c/0x510 ubifs_writepage+0x190/0x4dc __writepage+0x58/0x154 write_cache_pages+0x394/0x830 do_writepages+0x1f0/0x5b0 filemap_fdatawrite_wbc+0x170/0x25c file_write_and_wait_range+0x140/0x190 ubifs_fsync+0xe8/0x290 vfs_fsync_range+0xc0/0x1e4 do_fsync+0x40/0x90 __arm64_sys_fsync+0x34/0x50 invoke_syscall.constprop.0+0xa8/0x260 do_el0_svc+0xc8/0x1f0 el0_svc+0x34/0x70 el0t_64_sync_handler+0x108/0x114 el0t_64_sync+0x1a4/0x1a8 Freed by task 403: kasan_save_stack+0x38/0x70 kasan_set_track+0x28/0x40 kasan_set_free_info+0x28/0x4c __kasan_slab_free+0xd4/0x13c kfree+0xc4/0x3a0 tnc_delete+0x3f4/0xe40 ubifs_tnc_remove_range+0x368/0x73c ubifs_tnc_remove_ino+0x29c/0x2e0 ubifs_jnl_delete_inode+0x150/0x260 ubifs_evict_inode+0x1d4/0x2e4 evict+0x1c8/0x450 iput+0x2a0/0x3c4 do_unlinkat+0x2cc/0x490 __arm64_sys_unlinkat+0x90/0x100 invoke_syscall.constprop.0+0xa8/0x260 do_el0_svc+0xc8/0x1f0 el0_svc+0x34/0x70 el0t_64_sync_handler+0x108/0x114 el0t_64_sync+0x1a4/0x1a8
The offending memcpy() in ubifs_copy_hash() has a use-after-free when a node becomes root in TNC but still has a cparent to an already freed node. More specifically, consider the following TNC:
zroot
/
/
zp1
/
/
znInserting a new node zn_new with a key smaller then zn will trigger a split in tnc_insert() if zp1 is full:
zroot
/ \
/ \
zp1 zp2
/ \
/ \ zn_new zn
zn->parent has now been moved to zp2, *but* zn->cparent still points to zp1.
Now, consider a removal of all the nodes _except_ zn. Just when tnc_delete() is about to delete zroot and zp2:
zroot
\
\
zp2
\
\
znzroot and zp2 get freed and the tree collapses:
zn
zn now becomes the new zroot.
get_znodes_to_commit() will now only find zn, the new zroot, and write_index() will check its znode->cparent that wrongly points to the already freed zp1. ubifs_copy_hash() thus gets wrongly called with znode->cparent->zbranch[znode->iip].hash that triggers the use-after-free!
Fix this by explicitly setting znode->cparent to NULL in get_znodes_to_commit() for the root node. The search for the dirty nodes is bottom-up in the tree. Thus, when find_next_dirty(znode) returns NULL, the current znode _is_ the root node. Add an assert for this.
--- fs/ubifs/tnc_commit.c | 2 ++ 1 file changed, 2 insertions(+)
fs/ubifs/tnc_commit.c +2 -0
@@ -657,6 +657,8 @@ static int get_znodes_to_commit(struct ubifs_info *c) znode->alt =0 ; cnext =find_next_dirty (znode);if (!cnext) { +ubifs_assert (c, !znode->parent); + znode->cparent =NULL ; znode->cnext = c->cnext;break ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 565/676 jffs2: fix use of uninitialized variable
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qingfang Deng <[email protected]>
[ Upstream commit 3ba44ee966bc3c41dd8a944f963466c8fcc60dc8 ]
When building the kernel with -Wmaybe-uninitialized, the compiler reports this warning:
In function 'jffs2_mark_erased_block',
inlined from 'jffs2_erase_pending_blocks' at fs/jffs2/erase.c:116:4:fs/jffs2/erase.c:474:9: warning: 'bad_offset' may be used uninitialized [-Wmaybe-uninitialized]
474 | jffs2_erase_failed(c, jeb, bad_offset);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fs/jffs2/erase.c: In function 'jffs2_erase_pending_blocks':
fs/jffs2/erase.c:402:18: note: 'bad_offset' was declared here
402 | uint32_t bad_offset;
| ^~~~~~~~~~When mtd->point() is used, jffs2_erase_pending_blocks can return -EIO without initializing bad_offset, which is later used at the filebad label in jffs2_mark_erased_block.
Fix it by initializing this variable.
--- fs/jffs2/erase.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
fs/jffs2/erase.c +3 -4
@@ -338,10 +338,9 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl }while (--retlen);mtd_unpoint (c->mtd, jeb->offset, c->sector_size);if (retlen) { -pr_warn ("Newly-erased block contained word 0x%lx at offset 0x%08tx\n" , - *wordebuf, - jeb->offset + - c->sector_size-retlen *sizeof (*wordebuf)); + *bad_offset = jeb->offset + c->sector_size - retlen *sizeof (*wordebuf); +pr_warn ("Newly-erased block contained word 0x%lx at offset 0x%08x\n" , + *wordebuf, *bad_offset);return -EIO ; }return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 566/676 rtc: rzn1: fix BCD to rtc_time conversion errors
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wolfram Sang <[email protected]>
[ Upstream commit 55727188dfa3572aecd946e58fab9e4a64f06894 ]
tm_mon describes months from 0 to 11, but the register contains BCD from 1 to 12. tm_year contains years since 1900, but the BCD contains 20XX. Apply the offsets when converting these numbers.
--- drivers/rtc/rtc-rzn1.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/rtc/rtc-rzn1.c +4 -4
@@ -111,8 +111,8 @@ static int rzn1_rtc_read_time(struct device *dev, struct rtc_time *tm) tm->tm_hour =bcd2bin (tm->tm_hour); tm->tm_wday =bcd2bin (tm->tm_wday); tm->tm_mday =bcd2bin (tm->tm_mday); - tm->tm_mon =bcd2bin (tm->tm_mon); - tm->tm_year =bcd2bin (tm->tm_year); + tm->tm_mon =bcd2bin (tm->tm_mon) -1 ; + tm->tm_year =bcd2bin (tm->tm_year) +100 ;return 0 ; }
@@ -128,8 +128,8 @@ static int rzn1_rtc_set_time(struct device *dev, struct rtc_time *tm) tm->tm_hour =bin2bcd (tm->tm_hour); tm->tm_wday =bin2bcd (rzn1_rtc_tm_to_wday (tm)); tm->tm_mday =bin2bcd (tm->tm_mday); - tm->tm_mon =bin2bcd (tm->tm_mon); - tm->tm_year =bin2bcd (tm->tm_year); + tm->tm_mon =bin2bcd (tm->tm_mon +1 ); + tm->tm_year =bin2bcd (tm->tm_year -100 ); val =readl (rtc->base +RZN1_RTC_CTL2 );if (!(val &RZN1_RTC_CTL2_STOPPED )) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 567/676 nvme-multipath: prepare for "queue-depth" iopolicy
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Meneghini <[email protected]>
[ Upstream commit 3d7c2fd2ea704812867f9586270a2516377482a3 ]
This patch prepares for the introduction of a new iopolicy by breaking up the nvme_find_path() code path into sub-routines.
Stable-dep-of: 5dd18f09ce73 ("nvme/multipath: Fix RCU list traversal to use SRCU primitive")
--- drivers/nvme/host/multipath.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-)
drivers/nvme/host/multipath.c +15 -6
@@ -290,10 +290,15 @@ static struct nvme_ns *nvme_next_ns(struct nvme_ns_head *head, return list_first_or_null_rcu(&head->list, struct nvme_ns, siblings); } -static struct nvme_ns *nvme_round_robin_path (struct nvme_ns_head *head, -int node,struct nvme_ns *old) +static struct nvme_ns *nvme_round_robin_path (struct nvme_ns_head *head) {struct nvme_ns *ns, *found =NULL ; +int node =numa_node_id (); +struct nvme_ns *old =srcu_dereference (head->current_path[node], + &head->srcu); + +if (unlikely (!old)) +return __nvme_find_path (head, node);if (list_is_singular (&head->list)) {if (nvme_path_is_disabled (old))
@@ -339,7 +344,7 @@ static inline bool nvme_path_is_optimized(struct nvme_ns *ns) ns->ana_state ==NVME_ANA_OPTIMIZED ; } -inline struct nvme_ns *nvme_find_path (struct nvme_ns_head *head) +static struct nvme_ns *nvme_numa_path (struct nvme_ns_head *head) {int node =numa_node_id ();struct nvme_ns *ns;
@@ -347,14 +352,18 @@ inline struct nvme_ns *nvme_find_path(struct nvme_ns_head *head) ns =srcu_dereference (head->current_path[node], &head->srcu);if (unlikely (!ns))return __nvme_find_path (head, node); - -if (READ_ONCE (head->subsys->iopolicy) ==NVME_IOPOLICY_RR ) -return nvme_round_robin_path (head, node, ns);if (unlikely (!nvme_path_is_optimized (ns)))return __nvme_find_path (head, node);return ns; } +inline struct nvme_ns *nvme_find_path (struct nvme_ns_head *head) +{ +if (READ_ONCE (head->subsys->iopolicy) ==NVME_IOPOLICY_RR ) +return nvme_round_robin_path (head); +return nvme_numa_path (head); +} +static bool nvme_available_path (struct nvme_ns_head *head) {struct nvme_ns *ns;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 568/676 nvme-multipath: implement "queue-depth" iopolicy
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Song <[email protected]>
[ Upstream commit f227345f0a70f011647ae7ae12778bf258ff71f2 ]
The round-robin path selector is inefficient in cases where there is a difference in latency between paths. In the presence of one or more high latency paths the round-robin selector continues to use the high latency path equally. This results in a bias towards the highest latency path and can cause a significant decrease in overall performance as IOs pile on the highest latency path. This problem is acute with NVMe-oF controllers.
The queue-depth path selector sends I/O down the path with the lowest number of requests in its request queue. Paths with lower latency will clear requests more quickly and have less requests queued compared to higher latency paths. The goal of this path selector is to make more use of lower latency paths which will bring down overall IO latency and increase throughput and performance.
Stable-dep-of: 5dd18f09ce73 ("nvme/multipath: Fix RCU list traversal to use SRCU primitive")
--- drivers/nvme/host/core.c | 2 +- drivers/nvme/host/multipath.c | 86 +++++++++++++++++++++++++++++++++-- drivers/nvme/host/nvme.h | 4 ++ 3 files changed, 87 insertions(+), 5 deletions(-)
drivers/nvme/host/core.c +1 -1
@@ -109,7 +109,7 @@ struct workqueue_struct *nvme_delete_wq;EXPORT_SYMBOL_GPL (nvme_delete_wq);static LIST_HEAD (nvme_subsystems); -static DEFINE_MUTEX (nvme_subsystems_lock); +DEFINE_MUTEX (nvme_subsystems_lock);static DEFINE_IDA (nvme_instance_ida);static dev_t nvme_ctrl_base_chr_devt;
drivers/nvme/host/multipath.c +82 -4
147 lines not on this page · raw message
drivers/nvme/host/nvme.h +4 -0
@@ -48,6 +48,7 @@ extern unsigned int admin_timeout;extern struct workqueue_struct *nvme_wq;extern struct workqueue_struct *nvme_reset_wq;extern struct workqueue_struct *nvme_delete_wq; +extern struct mutex nvme_subsystems_lock;/* * List of workarounds for devices that required behavior not specified in
@@ -199,6 +200,7 @@ enum {NVME_REQ_CANCELLED = (1 <<0 ),NVME_REQ_USERCMD = (1 <<1 ),NVME_MPATH_IO_STATS = (1 <<2 ), + NVME_MPATH_CNT_ACTIVE = (1 << 3), };static inline struct nvme_request *nvme_req (struct request *req)
@@ -364,6 +366,7 @@ struct nvme_ctrl {size_t ana_log_size;struct timer_list anatt_timer;struct work_struct ana_work; +atomic_t nr_active;#endif #ifdef CONFIG_NVME_AUTH
@@ -411,6 +414,7 @@ static inline enum nvme_ctrl_state nvme_ctrl_state(struct nvme_ctrl *ctrl)enum nvme_iopolicy {NVME_IOPOLICY_NUMA ,NVME_IOPOLICY_RR , +NVME_IOPOLICY_QD , };struct nvme_subsystem {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 569/676 nvme-multipath: avoid hang on inaccessible namespaces
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hannes Reinecke <[email protected]>
[ Upstream commit 3b97f5a05cfc55e7729ff3769f63eef64e2178bb ]
During repetitive namespace remapping operations on the target the namespace might have changed between the time the initial scan was performed, and partition scan was invoked by device_add_disk() in nvme_mpath_set_live(). We then end up with a stuck scanning process:
[<0>] folio_wait_bit_common+0x12a/0x310 [<0>] filemap_read_folio+0x97/0xd0 [<0>] do_read_cache_folio+0x108/0x390 [<0>] read_part_sector+0x31/0xa0 [<0>] read_lba+0xc5/0x160 [<0>] efi_partition+0xd9/0x8f0 [<0>] bdev_disk_changed+0x23d/0x6d0 [<0>] blkdev_get_whole+0x78/0xc0 [<0>] bdev_open+0x2c6/0x3b0 [<0>] bdev_file_open_by_dev+0xcb/0x120 [<0>] disk_scan_partitions+0x5d/0x100 [<0>] device_add_disk+0x402/0x420 [<0>] nvme_mpath_set_live+0x4f/0x1f0 [nvme_core] [<0>] nvme_mpath_add_disk+0x107/0x120 [nvme_core] [<0>] nvme_alloc_ns+0xac6/0xe60 [nvme_core] [<0>] nvme_scan_ns+0x2dd/0x3e0 [nvme_core] [<0>] nvme_scan_work+0x1a3/0x490 [nvme_core]
This happens when we have several paths, some of which are inaccessible, and the active paths are removed first. Then nvme_find_path() will requeue I/O in the ns_head (as paths are present), but the requeue list is never triggered as all remaining paths are inactive.
This patch checks for NVME_NSHEAD_DISK_LIVE in nvme_available_path(), and requeue I/O after NVME_NSHEAD_DISK_LIVE has been cleared once the last path has been removed to properly terminate pending I/O.
Stable-dep-of: 5dd18f09ce73 ("nvme/multipath: Fix RCU list traversal to use SRCU primitive")
--- drivers/nvme/host/multipath.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
drivers/nvme/host/multipath.c +10 -2
@@ -420,6 +420,9 @@ static bool nvme_available_path(struct nvme_ns_head *head) {struct nvme_ns *ns; +if (!test_bit (NVME_NSHEAD_DISK_LIVE , &head->flags)) +return NULL ; +list_for_each_entry_rcu (ns, &head->list, siblings) {if (test_bit (NVME_CTRL_FAILFAST_EXPIRED , &ns->ctrl->flags))continue ;
@@ -996,8 +999,7 @@ void nvme_mpath_shutdown_disk(struct nvme_ns_head *head) {if (!head->disk)return ; -kblockd_schedule_work (&head->requeue_work); -if (test_bit (NVME_NSHEAD_DISK_LIVE , &head->flags)) { +if (test_and_clear_bit (NVME_NSHEAD_DISK_LIVE , &head->flags)) {nvme_cdev_del (&head->cdev, &head->cdev_device);/* * requeue I/O after NVME_NSHEAD_DISK_LIVE has been cleared
@@ -1007,6 +1009,12 @@ void nvme_mpath_shutdown_disk(struct nvme_ns_head *head)kblockd_schedule_work (&head->requeue_work);del_gendisk (head->disk); } +/* +* requeue I/O after NVME_NSHEAD_DISK_LIVE has been cleared +* to allow multipath to fail all I/O. +*/ +synchronize_srcu (&head->srcu); +kblockd_schedule_work (&head->requeue_work); }void nvme_mpath_remove_disk (struct nvme_ns_head *head)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 570/676 nvme/multipath: Fix RCU list traversal to use SRCU primitive
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
[ Upstream commit 5dd18f09ce7399df6fffe80d1598add46c395ae9 ]
The code currently uses list_for_each_entry_rcu() while holding an SRCU lock, triggering false positive warnings with CONFIG_PROVE_RCU=y enabled:
drivers/nvme/host/multipath.c:168 RCU-list traversed in non-reader section!! drivers/nvme/host/multipath.c:227 RCU-list traversed in non-reader section!! drivers/nvme/host/multipath.c:260 RCU-list traversed in non-reader section!!
While the list is properly protected by SRCU lock, the code uses the wrong list traversal primitive. Replace list_for_each_entry_rcu() with list_for_each_entry_srcu() to correctly indicate SRCU-based protection and eliminate the false warning.
--- drivers/nvme/host/multipath.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-)
drivers/nvme/host/multipath.c +14 -7
@@ -165,7 +165,8 @@ void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl)int srcu_idx; srcu_idx =srcu_read_lock (&ctrl->srcu); -list_for_each_entry_rcu (ns, &ctrl->namespaces, list) { +list_for_each_entry_srcu (ns, &ctrl->namespaces, list, +srcu_read_lock_held (&ctrl->srcu)) {if (!ns->head->disk)continue ;kblockd_schedule_work (&ns->head->requeue_work);
@@ -209,7 +210,8 @@ void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl)int srcu_idx; srcu_idx =srcu_read_lock (&ctrl->srcu); -list_for_each_entry_rcu (ns, &ctrl->namespaces, list) { +list_for_each_entry_srcu (ns, &ctrl->namespaces, list, +srcu_read_lock_held (&ctrl->srcu)) {nvme_mpath_clear_current_path (ns);kblockd_schedule_work (&ns->head->requeue_work); }
@@ -224,7 +226,8 @@ void nvme_mpath_revalidate_paths(struct nvme_ns *ns)int srcu_idx; srcu_idx =srcu_read_lock (&head->srcu); -list_for_each_entry_rcu (ns, &head->list, siblings) { +list_for_each_entry_srcu (ns, &head->list, siblings, +srcu_read_lock_held (&head->srcu)) {if (capacity !=get_capacity (ns->disk))clear_bit (NVME_NS_READY , &ns->flags); }
@@ -256,7 +259,8 @@ static struct nvme_ns *__nvme_find_path(struct nvme_ns_head *head, int node)int found_distance =INT_MAX , fallback_distance =INT_MAX , distance;struct nvme_ns *found =NULL , *fallback =NULL , *ns; -list_for_each_entry_rcu (ns, &head->list, siblings) { +list_for_each_entry_srcu (ns, &head->list, siblings, +srcu_read_lock_held (&head->srcu)) {if (nvme_path_is_disabled (ns))continue ;
@@ -355,7 +359,8 @@ static struct nvme_ns *nvme_queue_depth_path(struct nvme_ns_head *head)unsigned int min_depth_opt =UINT_MAX , min_depth_nonopt =UINT_MAX ;unsigned int depth; -list_for_each_entry_rcu (ns, &head->list, siblings) { +list_for_each_entry_srcu (ns, &head->list, siblings, +srcu_read_lock_held (&head->srcu)) {if (nvme_path_is_disabled (ns))continue ;
@@ -423,7 +428,8 @@ static bool nvme_available_path(struct nvme_ns_head *head)if (!test_bit (NVME_NSHEAD_DISK_LIVE , &head->flags))return NULL ; -list_for_each_entry_rcu (ns, &head->list, siblings) { +list_for_each_entry_srcu (ns, &head->list, siblings, +srcu_read_lock_held (&head->srcu)) {if (test_bit (NVME_CTRL_FAILFAST_EXPIRED , &ns->ctrl->flags))continue ;switch (ns->ctrl->state) {
@@ -784,7 +790,8 @@ static int nvme_update_ana_state(struct nvme_ctrl *ctrl,return 0 ; srcu_idx =srcu_read_lock (&ctrl->srcu); -list_for_each_entry_rcu (ns, &ctrl->namespaces, list) { +list_for_each_entry_srcu (ns, &ctrl->namespaces, list, +srcu_read_lock_held (&ctrl->srcu)) {unsigned nsid; again: nsid =le32_to_cpu (desc->nsids[n]);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 571/676 block: return unsigned int from bdev_io_min
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <[email protected]>
[ Upstream commit 46fd48ab3ea3eb3bb215684bd66ea3d260b091a9 ]
The underlying limit is defined as an unsigned int, so return that from bdev_io_min as well.
--- include/linux/blkdev.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/blkdev.h +1 -1
@@ -1184,7 +1184,7 @@ static inline unsigned int queue_io_min(const struct request_queue *q)return q->limits.io_min; } -static inline int bdev_io_min (struct block_device *bdev) +static inline unsigned int bdev_io_min (struct block_device *bdev) {return queue_io_min (bdev_get_queue (bdev)); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 572/676 9p/xen: fix init sequence
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Zenla <[email protected]>
[ Upstream commit 7ef3ae82a6ebbf4750967d1ce43bcdb7e44ff74b ]
Large amount of mount hangs observed during hotplugging of 9pfs devices. The 9pfs Xen driver attempts to initialize itself more than once, causing the frontend and backend to disagree: the backend listens on a channel that the frontend does not send on, resulting in stalled processing.
Only allow initialization of 9p frontend once.
Message-ID: <[email protected]>
--- net/9p/trans_xen.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
net/9p/trans_xen.c +5 -2
@@ -466,6 +466,7 @@ static int xen_9pfs_front_init(struct xenbus_device *dev) goto error; } +xenbus_switch_state (dev, XenbusStateInitialised);return 0 ; error_xenbus:
@@ -513,8 +514,10 @@ static void xen_9pfs_front_changed(struct xenbus_device *dev,break ;case XenbusStateInitWait: -if (!xen_9pfs_front_init (dev)) -xenbus_switch_state (dev, XenbusStateInitialised); +if (dev->state != XenbusStateInitialising) +break ; + +xen_9pfs_front_init (dev);break ;case XenbusStateConnected:
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 573/676 9p/xen: fix release of IRQ
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Zenla <[email protected]>
[ Upstream commit e43c608f40c065b30964f0a806348062991b802d ]
Kernel logs indicate an IRQ was double-freed.
Pass correct device ID during IRQ release.
Message-ID: <[email protected]>
--- net/9p/trans_xen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/9p/trans_xen.c +1 -1
@@ -287,7 +287,7 @@ static void xen_9pfs_front_free(struct xen_9pfs_front_priv *priv)if (!priv->rings[i].intf)break ;if (priv->rings[i].irq >0 ) -unbind_from_irqhandler (priv->rings[i].irq, priv->dev); +unbind_from_irqhandler (priv->rings[i].irq, ring);if (priv->rings[i].data.in) { for (j = 0; j < (1 << priv->rings[i].intf->ring_order);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 574/676 perf/arm-smmuv3: Fix lockdep assert in ->event_init()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chun-Tse Shao <[email protected]>
[ Upstream commit 02a55f2743012a8089f09f6867220c3d57f16564 ]
Same as
https://lore.kernel.org/all/[email protected]/,
we should skip for_each_sibling_event() for group leader since it doesn't have the ctx yet.
--- drivers/perf/arm_smmuv3_pmu.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-)
drivers/perf/arm_smmuv3_pmu.c +11 -8
@@ -431,6 +431,17 @@ static int smmu_pmu_event_init(struct perf_event *event)return -EINVAL ; } +/* +* Ensure all events are on the same cpu so all events are in the +* same cpu context, to avoid races on pmu_enable etc. +*/ + event->cpu = smmu_pmu->on_cpu; + + hwc->idx =-1 ; + +if (event->group_leader == event) +return 0 ; +for_each_sibling_event (sibling, event->group_leader) {if (is_software_event (sibling))continue ;
@@ -442,14 +453,6 @@ static int smmu_pmu_event_init(struct perf_event *event)return -EINVAL ; } - hwc->idx =-1 ; - -/* -* Ensure all events are on the same cpu so all events are in the -* same cpu context, to avoid races on pmu_enable etc. -*/ - event->cpu = smmu_pmu->on_cpu; -return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 575/676 perf/arm-cmn: Ensure port and device id bits are set properly
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namhyung Kim <[email protected]>
[ Upstream commit dfdf714fed559c09021df1d2a4bb64c0ad5f53bc ]
The portid_bits and deviceid_bits were set only for XP type nodes in the arm_cmn_discover() and it confused other nodes to find XP nodes. Copy the both bits from the XP nodes directly when it sets up a new node.
--- drivers/perf/arm-cmn.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/perf/arm-cmn.c +2 -2
@@ -2075,8 +2075,6 @@ static int arm_cmn_init_dtcs(struct arm_cmn *cmn)continue ; xp =arm_cmn_node_to_xp (cmn, dn); - dn->portid_bits = xp->portid_bits; - dn->deviceid_bits = xp->deviceid_bits; dn->dtc = xp->dtc; dn->dtm = xp->dtm;if (cmn->multi_dtm)
@@ -2307,6 +2305,8 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset) }arm_cmn_init_node_info (cmn, reg &CMN_CHILD_NODE_ADDR , dn); + dn->portid_bits = xp->portid_bits; + dn->deviceid_bits = xp->deviceid_bits;switch (dn->type) {case CMN_TYPE_DTC :
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 576/676 smb: client: disable directory caching when dir_cache_timeout is zero
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Henrique Carvalho <[email protected]>
[ Upstream commit ceaf1451990e3ea7fb50aebb5a149f57945f6e9f ]
Setting dir_cache_timeout to zero should disable the caching of directory contents. Currently, even when dir_cache_timeout is zero, some caching related functions are still invoked, which is unintended behavior.
Fix the issue by setting tcon->nohandlecache to true when dir_cache_timeout is zero, ensuring that directory handle caching is properly disabled.
--- fs/smb/client/connect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/smb/client/connect.c +1 -1
@@ -2601,7 +2601,7 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)if (ses->server->dialect >=SMB20_PROT_ID && (ses->server->capabilities &SMB2_GLOBAL_CAP_DIRECTORY_LEASING )) - nohandlecache = ctx->nohandlecache; + nohandlecache = ctx->nohandlecache || !dir_cache_timeout;else nohandlecache = true; tcon =tcon_info_alloc (!nohandlecache, netfs_trace_tcon_ref_new);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 577/676 cifs: Fix parsing native symlinks relative to the export
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pali Rohár <[email protected]>
[ Upstream commit 723f4ef90452aa629f3d923e92e0449d69362b1d ]
SMB symlink which has SYMLINK_FLAG_RELATIVE set is relative (as opposite of the absolute) and it can be relative either to the current directory (where is the symlink stored) or relative to the top level export path. To what it is relative depends on the first character of the symlink target path.
If the first character is path separator then symlink is relative to the export, otherwise to the current directory. Linux (and generally POSIX systems) supports only symlink paths relative to the current directory where is symlink stored.
Currently if Linux SMB client reads relative SMB symlink with first character as path separator (slash), it let as is. Which means that Linux interpret it as absolute symlink pointing from the root (/). But this location is different than the top level directory of SMB export (unless SMB export was mounted to the root) and thefore SMB symlinks relative to the export are interpreted wrongly by Linux SMB client.
Fix this problem. As Linux does not have equivalent of the path relative to the top of the mount point, convert such symlink target path relative to the current directory. Do this by prepending "../" pattern N times before the SMB target path, where N is the number of path separators found in SMB symlink path.
So for example, if SMB share is mounted to Linux path /mnt/share/, symlink is stored in file /mnt/share/test/folder1/symlink (so SMB symlink path is test\folder1\symlink) and SMB symlink target points to \test\folder2\file, then convert symlink target path to Linux path ../../test/folder2/file.
Deduplicate code for parsing SMB symlinks in native form from functions smb2_parse_symlink_response() and parse_reparse_native_symlink() into new function smb2_parse_native_symlink() and pass into this new function a new full_path parameter from callers, which specify SMB full path where is symlink stored.
This change fixes resolving of the native Windows symlinks relative to the top level directory of the SMB share.
Stable-dep-of: f4ca4f5a36ea ("cifs: Fix parsing reparse point with native symlink in SMB1 non-UNICODE session")
--- fs/smb/client/cifsglob.h | 1 + fs/smb/client/cifsproto.h | 1 + fs/smb/client/inode.c | 1 + fs/smb/client/reparse.c | 90 +++++++++++++++++++++++++++++++++------ fs/smb/client/reparse.h | 4 +- fs/smb/client/smb1ops.c | 3 +- fs/smb/client/smb2file.c | 21 +++++---- fs/smb/client/smb2inode.c | 6 ++- fs/smb/client/smb2proto.h | 9 +++- 9 files changed, 108 insertions(+), 28 deletions(-)
fs/smb/client/cifsglob.h +1 -0
@@ -592,6 +592,7 @@ struct smb_version_operations {/* Check for STATUS_NETWORK_NAME_DELETED */ bool (*is_network_name_deleted)(char *buf,struct TCP_Server_Info *srv);int (*parse_reparse_point)(struct cifs_sb_info *cifs_sb, +const char *full_path,struct kvec *rsp_iov,struct cifs_open_info_data *data); int (*create_reparse_symlink)(const unsigned int xid,
fs/smb/client/cifsproto.h +1 -0
@@ -679,6 +679,7 @@ char *extract_hostname(const char *unc);char *extract_sharename (const char *unc);int parse_reparse_point (struct reparse_data_buffer *buf,u32 plen,struct cifs_sb_info *cifs_sb, +const char *full_path,bool unicode,struct cifs_open_info_data *data); int cifs_sfu_make_node(unsigned int xid, struct inode *inode, struct dentry *dentry, struct cifs_tcon *tcon,
fs/smb/client/inode.c +1 -0
@@ -1054,6 +1054,7 @@ static int reparse_info_to_fattr(struct cifs_open_info_data *data, rc =0 ; }else if (iov && server->ops->parse_reparse_point) { rc = server->ops->parse_reparse_point (cifs_sb, + full_path, iov, data); }break ;
fs/smb/client/reparse.c +78 -12
127 lines not on this page · raw message
fs/smb/client/reparse.h +3 -1
@@ -117,7 +117,9 @@ int smb2_create_reparse_symlink(const unsigned int xid, struct inode *inode,int smb2_mknod_reparse (unsigned int xid,struct inode *inode,struct dentry *dentry,struct cifs_tcon *tcon,const char *full_path,umode_t mode,dev_t dev); -int smb2_parse_reparse_point (struct cifs_sb_info *cifs_sb,struct kvec *rsp_iov, +int smb2_parse_reparse_point (struct cifs_sb_info *cifs_sb, +const char *full_path, +struct kvec *rsp_iov,struct cifs_open_info_data *data);#endif /* _CIFS_REPARSE_H */
fs/smb/client/smb1ops.c +2 -1
@@ -994,6 +994,7 @@ static int cifs_query_symlink(const unsigned int xid, }static int cifs_parse_reparse_point (struct cifs_sb_info *cifs_sb, +const char *full_path,struct kvec *rsp_iov,struct cifs_open_info_data *data) {
@@ -1004,7 +1005,7 @@ static int cifs_parse_reparse_point(struct cifs_sb_info *cifs_sb, buf = (struct reparse_data_buffer *)((__u8 *)&io->hdr.Protocol +le32_to_cpu (io->DataOffset)); -return parse_reparse_point (buf, plen, cifs_sb, unicode, data); +return parse_reparse_point (buf, plen, cifs_sb, full_path, unicode, data); } static bool
fs/smb/client/smb2file.c +10 -11
@@ -63,12 +63,12 @@ static struct smb2_symlink_err_rsp *symlink_data(const struct kvec *iov)return sym; } -int smb2_parse_symlink_response (struct cifs_sb_info *cifs_sb,const struct kvec *iov,char **path) +int smb2_parse_symlink_response (struct cifs_sb_info *cifs_sb,const struct kvec *iov, +const char *full_path,char **path) {struct smb2_symlink_err_rsp *sym;unsigned int sub_offs, sub_len;unsigned int print_offs, print_len; -char *s;if (!cifs_sb || !iov || !iov->iov_base || !iov->iov_len || !path)return -EINVAL ;
@@ -86,15 +86,13 @@ int smb2_parse_symlink_response(struct cifs_sb_info *cifs_sb, const struct kvec iov->iov_len < SMB2_SYMLINK_STRUCT_SIZE + print_offs + print_len) return -EINVAL; - s =cifs_strndup_from_utf16 ((char *)sym->PathBuffer + sub_offs, sub_len, true, - cifs_sb->local_nls); -if (!s) -return -ENOMEM ; -convert_delimiter (s,'/' ); -cifs_dbg (FYI ,"%s: symlink target: %s\n" , __func__, s); - - *path = s; -return 0 ; +return smb2_parse_native_symlink (path, + (char *)sym->PathBuffer + sub_offs, + sub_len, + true, +le32_to_cpu (sym->Flags) &SYMLINK_FLAG_RELATIVE , + full_path, + cifs_sb); }int smb2_open_file (const unsigned int xid,struct cifs_open_parms *oparms,__u32 *oplock,void *buf)
@@ -126,6 +124,7 @@ int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32 goto out;if (hdr->Status ==STATUS_STOPPED_ON_SYMLINK ) { rc =smb2_parse_symlink_response (oparms->cifs_sb, &err_iov, + oparms->path, &data->symlink_target);if (!rc) {memset (smb2_data,0 ,sizeof (*smb2_data));
fs/smb/client/smb2inode.c +4 -2
@@ -828,6 +828,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,static int parse_create_response (struct cifs_open_info_data *data,struct cifs_sb_info *cifs_sb, +const char *full_path,const struct kvec *iov) {struct smb2_create_rsp *rsp = iov->iov_base;
@@ -841,6 +842,7 @@ static int parse_create_response(struct cifs_open_info_data *data,break ;case STATUS_STOPPED_ON_SYMLINK : rc =smb2_parse_symlink_response (cifs_sb, iov, + full_path, &data->symlink_target);if (rc)return rc;
@@ -930,14 +932,14 @@ int smb2_query_path_info(const unsigned int xid,switch (rc) {case 0 : - rc =parse_create_response (data, cifs_sb, &out_iov[0 ]); + rc =parse_create_response (data, cifs_sb, full_path, &out_iov[0 ]);break ;case -EOPNOTSUPP :/* * BB TODO: When support for special files added to Samba * re-verify this path. */ - rc =parse_create_response (data, cifs_sb, &out_iov[0 ]); + rc =parse_create_response (data, cifs_sb, full_path, &out_iov[0 ]);if (rc || !data->reparse_point) goto out;
fs/smb/client/smb2proto.h +8 -1
@@ -113,7 +113,14 @@ extern int smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,struct cifs_sb_info *cifs_sb, const unsigned char *path, char *pbuf, unsigned int *pbytes_read); -int smb2_parse_symlink_response (struct cifs_sb_info *cifs_sb,const struct kvec *iov,char **path); +int smb2_parse_native_symlink (char **target,const char *buf,unsigned int len, +bool unicode,bool relative, +const char *full_path, +struct cifs_sb_info *cifs_sb); +int smb2_parse_symlink_response (struct cifs_sb_info *cifs_sb, +const struct kvec *iov, +const char *full_path, +char **path);int smb2_open_file (const unsigned int xid,struct cifs_open_parms *oparms,__u32 *oplock,void *buf); extern int smb2_unlock_range(struct cifsFileInfo *cfile,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 578/676 cifs: Fix parsing reparse point with native symlink in SMB1 non-UNICODE session
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pali Rohár <[email protected]>
[ Upstream commit f4ca4f5a36eac9b4da378a0f28cbbe38534a0901 ]
SMB1 NT_TRANSACT_IOCTL/FSCTL_GET_REPARSE_POINT even in non-UNICODE mode returns reparse buffer in UNICODE/UTF-16 format.
This is because FSCTL_GET_REPARSE_POINT is NT-based IOCTL which does not distinguish between 8-bit non-UNICODE and 16-bit UNICODE modes and its path buffers are always encoded in UTF-16.
This change fixes reading of native symlinks in SMB1 when UNICODE session is not active.
--- fs/smb/client/smb1ops.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
fs/smb/client/smb1ops.c +1 -2
@@ -1000,12 +1000,11 @@ static int cifs_parse_reparse_point(struct cifs_sb_info *cifs_sb, {struct reparse_data_buffer *buf;TRANSACT_IOCTL_RSP *io = rsp_iov->iov_base; -bool unicode = !!(io->hdr.Flags2 &SMBFLG2_UNICODE );u32 plen =le16_to_cpu (io->ByteCount); buf = (struct reparse_data_buffer *)((__u8 *)&io->hdr.Protocol +le32_to_cpu (io->DataOffset)); -return parse_reparse_point (buf, plen, cifs_sb, full_path, unicode, data); +return parse_reparse_point (buf, plen, cifs_sb, full_path, true, data); } static bool
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 579/676 rtc: ab-eoz9: dont fail temperature reads on undervoltage notification
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maxime Chevallier <[email protected]>
[ Upstream commit e0779a0dcf41a6452ac0a169cd96863feb5787c7 ]
The undervoltage flags reported by the RTC are useful to know if the time and date are reliable after a reboot. Although the threshold VLOW1 indicates that the thermometer has been shutdown and time compensation is off, it doesn't mean that the temperature readout is currently impossible.
As the system is running, the RTC voltage is now fully established and we can read the temperature.
--- drivers/rtc/rtc-ab-eoz9.c | 7 ------- 1 file changed, 7 deletions(-)
drivers/rtc/rtc-ab-eoz9.c +0 -7
@@ -396,13 +396,6 @@ static int abeoz9z3_temp_read(struct device *dev,if (ret <0 )return ret; -if ((val &ABEOZ9_REG_CTRL_STATUS_V1F ) || - (val &ABEOZ9_REG_CTRL_STATUS_V2F )) { -dev_err (dev, -"thermometer might be disabled due to low voltage\n" ); -return -EINVAL ; - } -switch (attr) {case hwmon_temp_input: ret =regmap_read (regmap,ABEOZ9_REG_REG_TEMP , &val);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 580/676 modpost: remove ALL_EXIT_DATA_SECTIONS macro
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masahiro Yamada <[email protected]>
[ Upstream commit 3ada34b0f6559b2388f1983366614fbe8027b6fd ]
This is unused.
Stable-dep-of: bb43a59944f4 ("Rename .data.unlikely to .data..unlikely")
--- scripts/mod/modpost.c | 2 -- 1 file changed, 2 deletions(-)
scripts/mod/modpost.c +0 -2
@@ -794,8 +794,6 @@ static void check_section(const char *modname, struct elf_info *elf,#define ALL_INIT_DATA_SECTIONS \ ".init.setup", ".init.rodata", ".meminit.rodata", \ ".init.data", ".meminit.data" -#define ALL_EXIT_DATA_SECTIONS \ - ".exit.data", ".memexit.data"#define ALL_INIT_TEXT_SECTIONS \ ".init.text", ".meminit.text"
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 581/676 modpost: disallow *driver to reference .meminit* sections
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masahiro Yamada <[email protected]>
[ Upstream commit 50cccec15c48814765895891ca0d95d989b6a419 ]
Drivers must not reference .meminit* sections, which are discarded when CONFIG_MEMORY_HOTPLUG=n.
The reason for whitelisting "*driver" in the section mismatch check was to allow drivers to reference symbols annotated as __devinit or __devexit that existed in the past.
Those annotations were removed by the following commits:
- 54b956b90360 ("Remove __dev* markings from init.h")
- 92e9e6d1f984 ("modpost.c: Stop checking __dev* section mismatches")
Remove the stale whitelist.
Stable-dep-of: bb43a59944f4 ("Rename .data.unlikely to .data..unlikely")
--- scripts/mod/modpost.c | 6 ------ 1 file changed, 6 deletions(-)
scripts/mod/modpost.c +0 -6
@@ -1007,12 +1007,6 @@ static int secref_whitelist(const char *fromsec, const char *fromsym, "*_console")))return 0 ; -/* symbols in data sections that may refer to meminit sections */ -if (match (fromsec,PATTERNS (DATA_SECTIONS )) && -match (tosec,PATTERNS (ALL_XXXINIT_SECTIONS )) && -match (fromsym,PATTERNS ("*driver" ))) -return 0 ; -/* * symbols in data sections must not refer to .exit.*, but there are * quite a few offenders, so hide these unless for W=1 builds until
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 582/676 modpost: remove MEM_INIT_SECTIONS macro
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masahiro Yamada <[email protected]>
[ Upstream commit 473a45bb35f080e31cb4fe45e905bfe3bd407fdf ]
ALL_XXXINIT_SECTIONS and MEM_INIT_SECTIONS are the same. Remove the latter.
Stable-dep-of: bb43a59944f4 ("Rename .data.unlikely to .data..unlikely")
--- scripts/mod/modpost.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
scripts/mod/modpost.c +1 -2
@@ -805,7 +805,7 @@ static void check_section(const char *modname, struct elf_info *elf,".pci_fixup_enable" ,".pci_fixup_resume" , \ ".pci_fixup_resume_early", ".pci_fixup_suspend" -#define ALL_XXXINIT_SECTIONS MEM_INIT_SECTIONS +#define ALL_XXXINIT_SECTIONS ".meminit.*"#define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS#define ALL_EXIT_SECTIONS EXIT_SECTIONS
@@ -819,7 +819,6 @@ static void check_section(const char *modname, struct elf_info *elf, ".coldtext", ".softirqentry.text"#define INIT_SECTIONS ".init.*" -#define MEM_INIT_SECTIONS ".meminit.*"#define EXIT_SECTIONS ".exit.*"
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 583/676 modpost: remove EXIT_SECTIONS macro
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masahiro Yamada <[email protected]>
[ Upstream commit 48cd8df7afd1eef22cf7b125697a6d7c3d168c5c ]
ALL_EXIT_SECTIONS and EXIT_SECTIONS are the same. Remove the latter.
Stable-dep-of: bb43a59944f4 ("Rename .data.unlikely to .data..unlikely")
--- scripts/mod/modpost.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
scripts/mod/modpost.c +3 -5
@@ -808,7 +808,7 @@ static void check_section(const char *modname, struct elf_info *elf,#define ALL_XXXINIT_SECTIONS ".meminit.*"#define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS -#define ALL_EXIT_SECTIONS EXIT_SECTIONS +#define ALL_EXIT_SECTIONS ".exit.*"#define DATA_SECTIONS ".data", ".data.rel"#define TEXT_SECTIONS ".text", ".text.*", ".sched.text", \
@@ -820,8 +820,6 @@ static void check_section(const char *modname, struct elf_info *elf,#define INIT_SECTIONS ".init.*" -#define EXIT_SECTIONS ".exit.*" -#define ALL_TEXT_SECTIONS ALL_INIT_TEXT_SECTIONS, ALL_EXIT_TEXT_SECTIONS, \ TEXT_SECTIONS, OTHER_TEXT_SECTIONS
@@ -1013,7 +1011,7 @@ static int secref_whitelist(const char *fromsec, const char *fromsym,*/ if (!extra_warn &&match (fromsec,PATTERNS (DATA_SECTIONS )) && -match (tosec,PATTERNS (EXIT_SECTIONS )) && +match (tosec,PATTERNS (ALL_EXIT_SECTIONS )) &&match (fromsym,PATTERNS ("*driver" )))return 0 ;
@@ -1181,7 +1179,7 @@ static void check_export_symbol(struct module *mod, struct elf_info *elf,if (match (secname,PATTERNS (INIT_SECTIONS )))warn ("%s: %s: EXPORT_SYMBOL used for init symbol. Remove __init or EXPORT_SYMBOL.\n" , mod->name, name); -else if (match (secname,PATTERNS (EXIT_SECTIONS ))) +else if (match (secname,PATTERNS (ALL_EXIT_SECTIONS )))warn ("%s: %s: EXPORT_SYMBOL used for exit symbol. Remove __exit or EXPORT_SYMBOL.\n" , mod->name, name); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 584/676 modpost: disallow the combination of EXPORT_SYMBOL and __meminit*
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masahiro Yamada <[email protected]>
[ Upstream commit a3df1526da480c089c20868b7f4d486b9f266001 ]
Theoretically, we could export conditionally-discarded code sections, such as .meminit*, if all the users can become modular under a certain condition. However, that would be difficult to control and such a tricky case has never occurred.
Stable-dep-of: bb43a59944f4 ("Rename .data.unlikely to .data..unlikely")
--- scripts/mod/modpost.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/mod/modpost.c +1 -1
@@ -1176,7 +1176,7 @@ static void check_export_symbol(struct module *mod, struct elf_info *elf, ELF_ST_TYPE(sym->st_info) == STT_LOPROC) s->is_func = true; -if (match (secname,PATTERNS (INIT_SECTIONS ))) +if (match (secname,PATTERNS (ALL_INIT_SECTIONS )))warn ("%s: %s: EXPORT_SYMBOL used for init symbol. Remove __init or EXPORT_SYMBOL.\n" , mod->name, name);else if (match (secname,PATTERNS (ALL_EXIT_SECTIONS )))
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 585/676 modpost: use ALL_INIT_SECTIONS for the section check from DATA_SECTIONS
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masahiro Yamada <[email protected]>
[ Upstream commit e578e4e3110635b20786e442baa3aeff9bb65f95 ]
ALL_INIT_SECTIONS is defined as follows:
#define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS
Stable-dep-of: bb43a59944f4 ("Rename .data.unlikely to .data..unlikely")
--- scripts/mod/modpost.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/mod/modpost.c +1 -1
@@ -864,7 +864,7 @@ static const struct sectioncheck sectioncheck[] = { }, { .fromsec = { DATA_SECTIONS, NULL }, - .bad_tosec = { ALL_XXXINIT_SECTIONS, INIT_SECTIONS, NULL }, + .bad_tosec = { ALL_INIT_SECTIONS, NULL }, .mismatch = DATA_TO_ANY_INIT, }, {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 586/676 modpost: squash ALL_{INIT,EXIT}_TEXT_SECTIONS to ALL_TEXT_SECTIONS
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masahiro Yamada <[email protected]>
[ Upstream commit 34fcf231dcf94d7dea29c070228c4b93849f4850 ]
ALL_INIT_TEXT_SECTIONS and ALL_EXIT_TEXT_SECTIONS are only used in the macro definition of ALL_TEXT_SECTIONS.
Stable-dep-of: bb43a59944f4 ("Rename .data.unlikely to .data..unlikely")
--- scripts/mod/modpost.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
scripts/mod/modpost.c +1 -6
@@ -795,11 +795,6 @@ static void check_section(const char *modname, struct elf_info *elf,".init.setup" ,".init.rodata" ,".meminit.rodata" , \ ".init.data", ".meminit.data" -#define ALL_INIT_TEXT_SECTIONS \ - ".init.text", ".meminit.text" -#define ALL_EXIT_TEXT_SECTIONS \ - ".exit.text" -#define ALL_PCI_INIT_SECTIONS \ ".pci_fixup_early", ".pci_fixup_header", ".pci_fixup_final", \ ".pci_fixup_enable", ".pci_fixup_resume", \
@@ -820,7 +815,7 @@ static void check_section(const char *modname, struct elf_info *elf,#define INIT_SECTIONS ".init.*" -#define ALL_TEXT_SECTIONS ALL_INIT_TEXT_SECTIONS, ALL_EXIT_TEXT_SECTIONS, \ +#define ALL_TEXT_SECTIONS ".init.text", ".meminit.text", ".exit.text", \ TEXT_SECTIONS, OTHER_TEXT_SECTIONSenum mismatch {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 587/676 init/modpost: conditionally check section mismatch to __meminit*
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masahiro Yamada <[email protected]>
[ Upstream commit 73db3abdca58c8a014ec4c88cf5ef925cbf63669 ]
This reverts commit eb8f689046b8 ("Use separate sections for __dev/ _cpu/__mem code/data").
Check section mismatch to __meminit* only when CONFIG_MEMORY_HOTPLUG=n.
With this change, the linker script and modpost become simpler, and we can get rid of the __ref annotations from the memory hotplug code.
Stable-dep-of: bb43a59944f4 ("Rename .data.unlikely to .data..unlikely")
--- arch/powerpc/kernel/vmlinux.lds.S | 2 -- include/asm-generic/vmlinux.lds.h | 18 ++---------------- include/linux/init.h | 14 +++++++++----- scripts/mod/modpost.c | 19 ++++--------------- 4 files changed, 15 insertions(+), 38 deletions(-)
arch/powerpc/kernel/vmlinux.lds.S +0 -2
@@ -123,8 +123,6 @@ SECTIONS */ *(.sfpr); *(.text.asan.* .text.tsan.*) - MEM_KEEP(init.text) - MEM_KEEP(exit.text) } :text . = ALIGN(PAGE_SIZE);
include/asm-generic/vmlinux.lds.h +2 -16
@@ -139,14 +139,6 @@* often happens at runtime) */ -#if defined(CONFIG_MEMORY_HOTPLUG ) -#define MEM_KEEP (sec) *(.mem##sec) -#define MEM_DISCARD (sec) -#else -#define MEM_KEEP (sec) -#define MEM_DISCARD (sec) *(.mem##sec) -#endif -#ifndef CONFIG_HAVE_DYNAMIC_FTRACE_NO_PATCHABLE #define KEEP_PATCHABLE KEEP(*(__patchable_function_entries))#define PATCHABLE_DISCARDS
@@ -355,7 +347,6 @@ *(.data..decrypted) \ *(.ref.data) \ *(.data..shared_aligned) /* percpu related */ \ - MEM_KEEP(init.data*) \ *(.data.unlikely) \ __start_once = .; \ *(.data.once) \
@@ -519,7 +510,6 @@/* __*init sections */ \ __init_rodata : AT(ADDR(__init_rodata) - LOAD_OFFSET) { \ *(.ref.rodata) \ - MEM_KEEP(init.rodata) \ } \ \/* Built-in module parameters. */ \
@@ -570,8 +560,7 @@ *(.text.unknown .text.unknown.*) \ NOINSTR_TEXT \ *(.ref.text) \ - *(.text.asan.* .text.tsan.*) \ - MEM_KEEP(init.text*) \ + *(.text.asan.* .text.tsan.*)/* sched.text is aling to function alignment to secure we have same
@@ -678,7 +667,6 @@#define INIT_DATA \ KEEP(*(SORT(___kentry+*))) \ *(.init.data .init.data.*) \ - MEM_DISCARD(init.data*) \ KERNEL_CTORS() \ MCOUNT_REC() \ *(.init.rodata .init.rodata.*) \
@@ -686,7 +674,6 @@ TRACE_SYSCALLS() \ KPROBE_BLACKLIST() \ ERROR_INJECT_WHITELIST() \ - MEM_DISCARD(init.rodata) \ CLK_OF_TABLES() \ RESERVEDMEM_OF_TABLES() \TIMER_OF_TABLES () \
@@ -704,8 +691,7 @@#define INIT_TEXT \ *(.init.text .init.text.*) \ - *(.text.startup) \ - MEM_DISCARD(init.text*) + *(.text.startup)#define EXIT_DATA \ *(.exit.data .exit.data.*) \
include/linux/init.h +9 -5
@@ -84,11 +84,15 @@#define __exit __section(".exit.text") __exitused __cold notrace -/* Used for MEMORY_HOTPLUG */ -#define __meminit __section(".meminit.text") __cold notrace \ - __latent_entropy -#define __meminitdata __section(".meminit.data") -#define __meminitconst __section(".meminit.rodata") +#ifdef CONFIG_MEMORY_HOTPLUG +#define __meminit +#define __meminitdata +#define __meminitconst +#else +#define __meminit __init +#define __meminitdata __initdata +#define __meminitconst __initconst +#endif /* For assembly routines */ #define __HEAD .section ".head.text","ax"
scripts/mod/modpost.c +4 -15
@@ -792,17 +792,14 @@ static void check_section(const char *modname, struct elf_info *elf,#define ALL_INIT_DATA_SECTIONS \ - ".init.setup", ".init.rodata", ".meminit.rodata", \ - ".init.data", ".meminit.data" + ".init.setup", ".init.rodata", ".init.data"#define ALL_PCI_INIT_SECTIONS \ ".pci_fixup_early", ".pci_fixup_header", ".pci_fixup_final", \ ".pci_fixup_enable", ".pci_fixup_resume", \ ".pci_fixup_resume_early", ".pci_fixup_suspend" -#define ALL_XXXINIT_SECTIONS ".meminit.*" - -#define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS +#define ALL_INIT_SECTIONS ".init.*"#define ALL_EXIT_SECTIONS ".exit.*"#define DATA_SECTIONS ".data", ".data.rel"
@@ -813,9 +810,7 @@ static void check_section(const char *modname, struct elf_info *elf,".fixup" ,".entry.text" ,".exception.text" , \ ".coldtext", ".softirqentry.text" -#define INIT_SECTIONS ".init.*" - -#define ALL_TEXT_SECTIONS ".init.text", ".meminit.text", ".exit.text", \ +#define ALL_TEXT_SECTIONS ".init.text", ".exit.text", \ TEXT_SECTIONS, OTHER_TEXT_SECTIONS enum mismatch {
@@ -867,12 +862,6 @@ static const struct sectioncheck sectioncheck[] = { .bad_tosec = { ALL_EXIT_SECTIONS, NULL }, .mismatch = TEXTDATA_TO_ANY_EXIT, }, -/* Do not reference init code/data from meminit code/data */ -{ - .fromsec = { ALL_XXXINIT_SECTIONS, NULL }, - .bad_tosec = { INIT_SECTIONS, NULL }, - .mismatch = XXXINIT_TO_SOME_INIT, -}, /* Do not use exit code/data from init code */ { .fromsec = { ALL_INIT_SECTIONS, NULL },
@@ -887,7 +876,7 @@ static const struct sectioncheck sectioncheck[] = { }, { .fromsec = { ALL_PCI_INIT_SECTIONS, NULL }, - .bad_tosec = { INIT_SECTIONS, NULL }, + .bad_tosec = { ALL_INIT_SECTIONS, NULL }, .mismatch = ANY_INIT_TO_ANY_EXIT, }, {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 588/676 Rename .data.unlikely to .data..unlikely
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masahiro Yamada <[email protected]>
[ Upstream commit bb43a59944f45e89aa158740b8a16ba8f0b0fa2b ]
Commit 7ccaba5314ca ("consolidate WARN_...ONCE() static variables") was intended to collect all .data.unlikely sections into one chunk. However, this has not worked when CONFIG_LD_DEAD_CODE_DATA_ELIMINATION or CONFIG_LTO_CLANG is enabled, because .data.unlikely matches the .data.[0-9a-zA-Z_]* pattern in the DATA_MAIN macro.
Commit cb87481ee89d ("kbuild: linker script do not match C names unless LD_DEAD_CODE_DATA_ELIMINATION is configured") was introduced to suppress the issue for the default CONFIG_LD_DEAD_CODE_DATA_ELIMINATION=n case, providing a minimal fix for stable backporting. We were aware this did not address the issue for CONFIG_LD_DEAD_CODE_DATA_ELIMINATION=y. The plan was to apply correct fixes and then revert cb87481ee89d. [1]
Seven years have passed since then, yet the #ifdef workaround remains in place.
Using a ".." separator in the section name fixes the issue for CONFIG_LD_DEAD_CODE_DATA_ELIMINATION and CONFIG_LTO_CLANG.
--- include/asm-generic/vmlinux.lds.h | 2 +- include/linux/rcupdate.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
include/asm-generic/vmlinux.lds.h +1 -1
@@ -347,7 +347,7 @@ *(.data..decrypted) \ *(.ref.data) \ *(.data..shared_aligned) /* percpu related */ \ - *(.data.unlikely) \ + *(.data..unlikely) \ __start_once = .; \ *(.data.once) \ __end_once = .; \
include/linux/rcupdate.h +1 -1
@@ -398,7 +398,7 @@ static inline int debug_lockdep_rcu_enabled(void)*/ #define RCU_LOCKDEP_WARN (c, s) \ do { \ - static bool __section(".data.unlikely") __warned; \ + static bool __section(".data..unlikely") __warned; \ if (debug_lockdep_rcu_enabled() && (c) && \ debug_lockdep_rcu_enabled() && !__warned) { \ __warned = true; \
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 589/676 Rename .data.once to .data..once to fix resetting WARN*_ONCE
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masahiro Yamada <[email protected]>
[ Upstream commit dbefa1f31a91670c9e7dac9b559625336206466f ]
Commit b1fca27d384e ("kernel debug: support resetting WARN*_ONCE") added support for clearing the state of once warnings. However, it is not functional when CONFIG_LD_DEAD_CODE_DATA_ELIMINATION or CONFIG_LTO_CLANG is enabled, because .data.once matches the .data.[0-9a-zA-Z_]* pattern in the DATA_MAIN macro.
Commit cb87481ee89d ("kbuild: linker script do not match C names unless LD_DEAD_CODE_DATA_ELIMINATION is configured") was introduced to suppress the issue for the default CONFIG_LD_DEAD_CODE_DATA_ELIMINATION=n case, providing a minimal fix for stable backporting. We were aware this did not address the issue for CONFIG_LD_DEAD_CODE_DATA_ELIMINATION=y. The plan was to apply correct fixes and then revert cb87481ee89d. [1]
Seven years have passed since then, yet the #ifdef workaround remains in place. Meanwhile, commit b1fca27d384e introduced the .data.once section, and commit dc5723b02e52 ("kbuild: add support for Clang LTO") extended the #ifdef.
Using a ".." separator in the section name fixes the issue for CONFIG_LD_DEAD_CODE_DATA_ELIMINATION and CONFIG_LTO_CLANG.
--- include/asm-generic/vmlinux.lds.h | 2 +- include/linux/mmdebug.h | 6 +++--- include/linux/once.h | 4 ++-- include/linux/once_lite.h | 2 +- include/net/net_debug.h | 2 +- mm/internal.h | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-)
include/asm-generic/vmlinux.lds.h +1 -1
@@ -349,7 +349,7 @@ *(.data..shared_aligned) /* percpu related */ \ *(.data..unlikely) \ __start_once = .; \ - *(.data.once) \ + *(.data..once) \ __end_once = .; \STRUCT_ALIGN (); \ *(__tracepoints) \
include/linux/mmdebug.h +3 -3
@@ -46,7 +46,7 @@ void vma_iter_dump_tree(const struct vma_iterator *vmi); } \ } while (0)#define VM_WARN_ON_ONCE_PAGE (cond, page) ({ \ - static bool __section(".data.once") __warned; \ + static bool __section(".data..once") __warned; \ int __ret_warn_once = !!(cond); \ \ if (unlikely(__ret_warn_once && !__warned)) { \
@@ -66,7 +66,7 @@ void vma_iter_dump_tree(const struct vma_iterator *vmi);unlikely (__ret_warn); \ })#define VM_WARN_ON_ONCE_FOLIO (cond, folio) ({ \ - static bool __section(".data.once") __warned; \ + static bool __section(".data..once") __warned; \ int __ret_warn_once = !!(cond); \ \ if (unlikely(__ret_warn_once && !__warned)) { \
@@ -77,7 +77,7 @@ void vma_iter_dump_tree(const struct vma_iterator *vmi);unlikely (__ret_warn_once); \ })#define VM_WARN_ON_ONCE_MM (cond, mm) ({ \ - static bool __section(".data.once") __warned; \ + static bool __section(".data..once") __warned; \ int __ret_warn_once = !!(cond); \ \ if (unlikely(__ret_warn_once && !__warned)) { \
include/linux/once.h +2 -2
@@ -46,7 +46,7 @@ void __do_once_sleepable_done(bool *done, struct static_key_true *once_key,#define DO_ONCE (func, ...) \ ({ \ bool ___ret = false; \ - static bool __section(".data.once") ___done = false; \ + static bool __section(".data..once") ___done = false; \ static DEFINE_STATIC_KEY_TRUE(___once_key); \ if (static_branch_unlikely(&___once_key)) { \ unsigned long ___flags; \
@@ -64,7 +64,7 @@ void __do_once_sleepable_done(bool *done, struct static_key_true *once_key,#define DO_ONCE_SLEEPABLE (func, ...) \ ({ \ bool ___ret = false; \ - static bool __section(".data.once") ___done = false; \ + static bool __section(".data..once") ___done = false; \ static DEFINE_STATIC_KEY_TRUE(___once_key); \ if (static_branch_unlikely(&___once_key)) { \ ___ret = __do_once_sleepable_start(&___done); \
include/linux/once_lite.h +1 -1
@@ -12,7 +12,7 @@#define __ONCE_LITE_IF (condition) \ ({ \ - static bool __section(".data.once") __already_done; \ + static bool __section(".data..once") __already_done; \ bool __ret_cond = !!(condition); \ bool __ret_once = false; \ \
include/net/net_debug.h +1 -1
@@ -27,7 +27,7 @@ void netdev_info(const struct net_device *dev, const char *format, ...);#define netdev_level_once (level, dev, fmt, ...) \ do { \ - static bool __section(".data.once") __print_once; \ + static bool __section(".data..once") __print_once; \ \ if (!__print_once) { \ __print_once = true; \
mm/internal.h +1 -1
@@ -40,7 +40,7 @@ struct folio_batch;* when we specify __GFP_NOWARN. */ #define WARN_ON_ONCE_GFP (cond, gfp) ({ \ - static bool __section(".data.once") __warned; \ + static bool __section(".data..once") __warned; \ int __ret_warn_once = !!(cond); \ \ if (unlikely(!(gfp & __GFP_NOWARN) && __ret_warn_once && !__warned)) { \
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 590/676 smb: Initialize cfid->tcon before performing network ops
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Aurich <[email protected]>
[ Upstream commit c353ee4fb119a2582d0e011f66a76a38f5cf984d ]
Avoid leaking a tcon ref when a lease break races with opening the cached directory. Processing the leak break might take a reference to the tcon in cached_dir_lease_break() and then fail to release the ref in cached_dir_offload_close, since cfid->tcon is still NULL.
--- fs/smb/client/cached_dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/smb/client/cached_dir.c +1 -1
@@ -227,6 +227,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, } } cfid->dentry = dentry; + cfid->tcon = tcon;/* * We do not hold the lock for the open because in case
@@ -298,7 +299,6 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, } goto oshr_free; } - cfid->tcon = tcon; cfid->is_open = true;spin_lock (&cfids->cfid_list_lock);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 591/676 modpost: remove incorrect code in do_eisa_entry()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masahiro Yamada <[email protected]>
[ Upstream commit 0c3e091319e4748cb36ac9a50848903dc6f54054 ]
This function contains multiple bugs after the following commits:
- ac551828993e ("modpost: i2c aliases need no trailing wildcard")
- 6543becf26ff ("mod/file2alias: make modalias generation safe for cross compiling")
Commit ac551828993e inserted the following code to do_eisa_entry():
else
strcat(alias, "*");
This is incorrect because 'alias' is uninitialized. If it is not NULL-terminated, strcat() could cause a buffer overrun.
Even if 'alias' happens to be zero-filled, it would output:
MODULE_ALIAS("*");This would match anything. As a result, the module could be loaded by any unrelated uevent from an unrelated subsystem.
Commit ac551828993e introduced another bug.
Prior to that commit, the conditional check was:
if (eisa->sig[0])
This checked if the first character of eisa_device_id::sig was not '\0'.
However, commit ac551828993e changed it as follows:
if (sig[0])
sig[0] is NOT the first character of the eisa_device_id::sig. The type of 'sig' is 'char (*)[8]', meaning that the type of 'sig[0]' is 'char [8]' instead of 'char'. 'sig[0]' and 'symval' refer to the same address, which never becomes NULL.
The correct conversion would have been:
if ((*sig)[0])
However, this if-conditional was meaningless because the earlier change in commit ac551828993e was incorrect.
This commit removes the entire incorrect code, which should never have been executed.
--- scripts/mod/file2alias.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
scripts/mod/file2alias.c +1 -4
@@ -809,10 +809,7 @@ static int do_eisa_entry(const char *filename, void *symval, char *alias) {DEF_FIELD_ADDR (symval, eisa_device_id, sig); -if (sig[0 ]) -sprintf (alias,EISA_DEVICE_MODALIAS_FMT "*" , *sig); -else -strcat (alias,"*" ); +sprintf (alias,EISA_DEVICE_MODALIAS_FMT "*" , *sig);return 1 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 592/676 cifs: during remount, make sure passwords are in sync
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shyam Prasad N <[email protected]>
[ Upstream commit 0f0e357902957fba28ed31bde0d6921c6bd1485d ]
This fixes scenarios where remount can overwrite the only currently working password, breaking reconnect.
We recently introduced a password2 field in both ses and ctx structs. This was done so as to allow the client to rotate passwords for a mount without any downtime. However, when the client transparently handles password rotation, it can swap the values of the two password fields in the ses struct, but not in smb3_fs_context struct that hangs off cifs_sb. This can lead to a situation where a remount unintentionally overwrites a working password in the ses struct.
In order to fix this, we first get the passwords in ctx struct in-sync with ses struct, before replacing them with what the passwords that could be passed as a part of remount.
Also, in order to avoid race condition between smb2_reconnect and smb3_reconfigure, we make sure to lock session_mutex before changing password and password2 fields of the ses structure.
--- fs/smb/client/fs_context.c | 83 +++++++++++++++++++++++++++++++++----- fs/smb/client/fs_context.h | 1 + 2 files changed, 75 insertions(+), 9 deletions(-)
fs/smb/client/fs_context.c +74 -9
@@ -888,12 +888,37 @@ do { \ cifs_sb->ctx->field =NULL ; \ }while (0 ) +int smb3_sync_session_ctx_passwords(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses) +{ +if (ses->password && + cifs_sb->ctx->password && +strcmp (ses->password, cifs_sb->ctx->password)) { +kfree_sensitive (cifs_sb->ctx->password); + cifs_sb->ctx->password =kstrdup (ses->password,GFP_KERNEL ); +if (!cifs_sb->ctx->password) +return -ENOMEM ; + } +if (ses->password2 && + cifs_sb->ctx->password2 && +strcmp (ses->password2, cifs_sb->ctx->password2)) { +kfree_sensitive (cifs_sb->ctx->password2); + cifs_sb->ctx->password2 =kstrdup (ses->password2,GFP_KERNEL ); +if (!cifs_sb->ctx->password2) { +kfree_sensitive (cifs_sb->ctx->password); + cifs_sb->ctx->password =NULL ; +return -ENOMEM ; + } + } +return 0 ; +} +static int smb3_reconfigure (struct fs_context *fc) {struct smb3_fs_context *ctx =smb3_fc2context (fc);struct dentry *root = fc->root;struct cifs_sb_info *cifs_sb =CIFS_SB (root->d_sb);struct cifs_ses *ses =cifs_sb_master_tcon (cifs_sb)->ses; +char *new_password =NULL , *new_password2 =NULL ;bool need_recon = false;int rc;
@@ -913,21 +938,61 @@ static int smb3_reconfigure(struct fs_context *fc)STEAL_STRING (cifs_sb, ctx,UNC );STEAL_STRING (cifs_sb, ctx, source);STEAL_STRING (cifs_sb, ctx, username); +if (need_recon == false)STEAL_STRING_SENSITIVE (cifs_sb, ctx, password);else { -kfree_sensitive (ses->password); - ses->password =kstrdup (ctx->password,GFP_KERNEL ); -if (!ses->password) -return -ENOMEM ; -kfree_sensitive (ses->password2); - ses->password2 =kstrdup (ctx->password2,GFP_KERNEL ); -if (!ses->password2) { -kfree_sensitive (ses->password); - ses->password =NULL ; +if (ctx->password) { + new_password =kstrdup (ctx->password,GFP_KERNEL ); +if (!new_password) +return -ENOMEM ; + }else +STEAL_STRING_SENSITIVE (cifs_sb, ctx, password); + } + +/* +* if a new password2 has been specified, then reset it's value +* inside the ses struct +*/ +if (ctx->password2) { + new_password2 =kstrdup (ctx->password2,GFP_KERNEL ); +if (!new_password2) { +kfree_sensitive (new_password);return -ENOMEM ; } + }else +STEAL_STRING_SENSITIVE (cifs_sb, ctx, password2); + +/* +* we may update the passwords in the ses struct below. Make sure we do +* not race with smb2_reconnect +*/ +mutex_lock (&ses->session_mutex); + +/* +* smb2_reconnect may swap password and password2 in case session setup +* failed. First get ctx passwords in sync with ses passwords. It should +* be okay to do this even if this function were to return an error at a +* later stage +*/ + rc =smb3_sync_session_ctx_passwords (cifs_sb, ses); +if (rc) +return rc; + +/* +* now that allocations for passwords are done, commit them +*/ +if (new_password) { +kfree_sensitive (ses->password); + ses->password = new_password; } +if (new_password2) { +kfree_sensitive (ses->password2); + ses->password2 = new_password2; + } + +mutex_unlock (&ses->session_mutex); +STEAL_STRING (cifs_sb, ctx, domainname);STEAL_STRING (cifs_sb, ctx, nodename);STEAL_STRING (cifs_sb, ctx, iocharset);
fs/smb/client/fs_context.h +1 -0
@@ -298,6 +298,7 @@ static inline struct smb3_fs_context *smb3_fc2context(const struct fs_context *f }extern int smb3_fs_context_dup (struct smb3_fs_context *new_ctx,struct smb3_fs_context *ctx); +extern int smb3_sync_session_ctx_passwords (struct cifs_sb_info *cifs_sb,struct cifs_ses *ses);extern void smb3_update_mnt_flags (struct cifs_sb_info *cifs_sb);/*
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 593/676 cifs: unlock on error in smb3_reconfigure()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit cda88d2fef7aa7de80b5697e8009fcbbb436f42d ]
Unlock before returning if smb3_sync_session_ctx_passwords() fails.
--- fs/smb/client/fs_context.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
fs/smb/client/fs_context.c +3 -1
@@ -976,8 +976,10 @@ static int smb3_reconfigure(struct fs_context *fc)* later stage */ rc =smb3_sync_session_ctx_passwords (cifs_sb, ses); -if (rc) +if (rc) { +mutex_unlock (&ses->session_mutex);return rc; + }/* * now that allocations for passwords are done, commit them
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 594/676 nfs: ignore SB_RDONLY when mounting nfs
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Lingfeng <[email protected]>
[ Upstream commit 52cb7f8f177878b4f22397b9c4d2c8f743766be3 ]
When exporting only one file system with fsid=0 on the server side, the client alternately uses the ro/rw mount options to perform the mount operation, and a new vfsmount is generated each time.
It can be reproduced as follows:
[root@localhost ~]# mount /dev/sda /mnt2
[root@localhost ~]# echo "/mnt2 *(rw,no_root_squash,fsid=0)" >/etc/exports [root@localhost ~]# systemctl restart nfs-server [root@localhost ~]# mount -t nfs -o ro,vers=4 127.0.0.1:/ /mnt/sdaa [root@localhost ~]# mount -t nfs -o rw,vers=4 127.0.0.1:/ /mnt/sdaa [root@localhost ~]# mount -t nfs -o ro,vers=4 127.0.0.1:/ /mnt/sdaa [root@localhost ~]# mount -t nfs -o rw,vers=4 127.0.0.1:/ /mnt/sdaa [root@localhost ~]# mount | grep nfs4
127.0.0.1:/ on /mnt/sdaa type nfs4 (ro,relatime,vers=4.2,rsize=1048576,... 127.0.0.1:/ on /mnt/sdaa type nfs4 (rw,relatime,vers=4.2,rsize=1048576,... 127.0.0.1:/ on /mnt/sdaa type nfs4 (ro,relatime,vers=4.2,rsize=1048576,... 127.0.0.1:/ on /mnt/sdaa type nfs4 (rw,relatime,vers=4.2,rsize=1048576,... [root@localhost ~]#
We expected that after mounting with the ro option, using the rw option to mount again would return EBUSY, but the actual situation was not the case.
As shown above, when mounting for the first time, a superblock with the ro flag will be generated, and at the same time, in do_new_mount_fc --> do_add_mount, it detects that the superblock corresponding to the current target directory is inconsistent with the currently generated one (path->mnt->mnt_sb != newmnt->mnt.mnt_sb), and a new vfsmount will be generated.
When mounting with the rw option for the second time, since no matching superblock can be found in the fs_supers list, a new superblock with the rw flag will be generated again. The superblock in use (ro) is different from the newly generated superblock (rw), and a new vfsmount will be generated again.
When mounting with the ro option for the third time, the superblock (ro) is found in fs_supers, the superblock in use (rw) is different from the found superblock (ro), and a new vfsmount will be generated again.
We can switch between ro/rw through remount, and only one superblock needs to be generated, thus avoiding the problem of repeated generation of vfsmount caused by switching superblocks.
Furthermore, This can also resolve the issue described in the link.
--- fs/nfs/internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfs/internal.h +1 -1
@@ -11,7 +11,7 @@#include <linux/nfs_page.h> #include <linux/wait_bit.h> -#define NFS_SB_MASK (SB_RDONLY|SB_NOSUID|SB_NODEV|SB_NOEXEC|SB_SYNCHRONOUS) +#define NFS_SB_MASK (SB_NOSUID|SB_NODEV|SB_NOEXEC|SB_SYNCHRONOUS)extern const struct export_operations nfs_export_ops;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 595/676 sunrpc: clear XPRT_SOCK_UPD_TIMEOUT when reset transport
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liu Jian <[email protected]>
[ Upstream commit 4db9ad82a6c823094da27de4825af693a3475d51 ]
Since transport->sock has been set to NULL during reset transport, XPRT_SOCK_UPD_TIMEOUT also needs to be cleared. Otherwise, the xs_tcp_set_socket_timeouts() may be triggered in xs_tcp_send_request() to dereference the transport->sock that has been set to NULL.
--- net/sunrpc/xprtsock.c | 1 + 1 file changed, 1 insertion(+)
net/sunrpc/xprtsock.c +1 -0
@@ -1186,6 +1186,7 @@ static void xs_sock_reset_state_flags(struct rpc_xprt *xprt)clear_bit (XPRT_SOCK_WAKE_WRITE , &transport->sock_state);clear_bit (XPRT_SOCK_WAKE_DISCONNECT , &transport->sock_state);clear_bit (XPRT_SOCK_NOSPACE , &transport->sock_state); +clear_bit (XPRT_SOCK_UPD_TIMEOUT , &transport->sock_state); }static void xs_run_error_worker (struct sock_xprt *transport,unsigned int nr)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 596/676 SUNRPC: timeout and cancel TLS handshake with -ETIMEDOUT
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Coddington <[email protected]>
[ Upstream commit d7bdd849ef1b681da03ac05ca0957b2cbe2d24b6 ]
We've noticed a situation where an unstable TCP connection can cause the TLS handshake to timeout waiting for userspace to complete it. When this happens, we don't want to return from xs_tls_handshake_sync() with zero, as this will cause the upper xprt to be set CONNECTED, and subsequent attempts to transmit will be returned with -EPIPE. The sunrpc machine does not recover from this situation and will spin attempting to transmit.
The return value of tls_handshake_cancel() can be used to detect a race with completion:
* tls_handshake_cancel - cancel a pending handshake
* Return values:
* %true - Uncompleted handshake request was canceled
* %false - Handshake request already completed or not found
If true, we do not want the upper xprt to be connected, so return -ETIMEDOUT. If false, its possible the handshake request was lost and that may be the reason for our timeout. Again we do not want the upper xprt to be connected, so return -ETIMEDOUT.
Ensure that we alway return an error from xs_tls_handshake_sync() if we call tls_handshake_cancel().
--- net/sunrpc/xprtsock.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
net/sunrpc/xprtsock.c +4 -5
@@ -2596,11 +2596,10 @@ static int xs_tls_handshake_sync(struct rpc_xprt *lower_xprt, struct xprtsec_par rc =wait_for_completion_interruptible_timeout (&lower_transport->handshake_done,XS_TLS_HANDSHAKE_TO );if (rc <=0 ) { -if (!tls_handshake_cancel (sk)) { -if (rc ==0 ) - rc = -ETIMEDOUT ; - goto out_put_xprt; - } +tls_handshake_cancel (sk); +if (rc ==0 ) + rc = -ETIMEDOUT ; + goto out_put_xprt; } rc = lower_transport->xprt_err;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 597/676 sunrpc: fix one UAF issue caused by sunrpc kernel tcp socket
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liu Jian <[email protected]>
[ Upstream commit 3f23f96528e8fcf8619895c4c916c52653892ec1 ]
BUG: KASAN: slab-use-after-free in tcp_write_timer_handler+0x156/0x3e0 Read of size 1 at addr ffff888111f322cd by task swapper/0/0 CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.12.0-rc4-dirty #7 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 Call Trace: <IRQ> dump_stack_lvl+0x68/0xa0 print_address_description.constprop.0+0x2c/0x3d0 print_report+0xb4/0x270 kasan_report+0xbd/0xf0 tcp_write_timer_handler+0x156/0x3e0 tcp_write_timer+0x66/0x170 call_timer_fn+0xfb/0x1d0 __run_timers+0x3f8/0x480 run_timer_softirq+0x9b/0x100 handle_softirqs+0x153/0x390 __irq_exit_rcu+0x103/0x120 irq_exit_rcu+0xe/0x20 sysvec_apic_timer_interrupt+0x76/0x90 </IRQ> <TASK> asm_sysvec_apic_timer_interrupt+0x1a/0x20 RIP: 0010:default_idle+0xf/0x20 Code: 4c 01 c7 4c 29 c2 e9 72 ff ff ff 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 66 90 0f 00 2d 33 f8 25 00 fb f4 <fa> c3 cc cc cc cc 66 66 2e 0f 1f 84 00 00 00 00 00 90 90 90 90 90 RSP: 0018:ffffffffa2007e28 EFLAGS: 00000242 RAX: 00000000000f3b31 RBX: 1ffffffff4400fc7 RCX: ffffffffa09c3196 RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffffff9f00590f RBP: 0000000000000000 R08: 0000000000000001 R09: ffffed102360835d R10: ffff88811b041aeb R11: 0000000000000001 R12: 0000000000000000 R13: ffffffffa202d7c0 R14: 0000000000000000 R15: 00000000000147d0 default_idle_call+0x6b/0xa0 cpuidle_idle_call+0x1af/0x1f0 do_idle+0xbc/0x130 cpu_startup_entry+0x33/0x40 rest_init+0x11f/0x210 start_kernel+0x39a/0x420 x86_64_start_reservations+0x18/0x30 x86_64_start_kernel+0x97/0xa0 common_startup_64+0x13e/0x141 </TASK> Allocated by task 595: kasan_save_stack+0x24/0x50 kasan_save_track+0x14/0x30 __kasan_slab_alloc+0x87/0x90 kmem_cache_alloc_noprof+0x12b/0x3f0 copy_net_ns+0x94/0x380 create_new_namespaces+0x24c/0x500 unshare_nsproxy_namespaces+0x75/0xf0 ksys_unshare+0x24e/0x4f0 __x64_sys_unshare+0x1f/0x30 do_syscall_64+0x70/0x180 entry_SYSCALL_64_after_hwframe+0x76/0x7e Freed by task 100: kasan_save_stack+0x24/0x50 kasan_save_track+0x14/0x30 kasan_save_free_info+0x3b/0x60 __kasan_slab_free+0x54/0x70 kmem_cache_free+0x156/0x5d0 cleanup_net+0x5d3/0x670 process_one_work+0x776/0xa90 worker_thread+0x2e2/0x560 kthread+0x1a8/0x1f0 ret_from_fork+0x34/0x60 ret_from_fork_asm+0x1a/0x30
Reproduction script:
mkdir -p /mnt/nfsshare
mkdir -p /mnt/nfs/netns_1
mkfs.ext4 /dev/sdb
mount /dev/sdb /mnt/nfsshare
systemctl restart nfs-server
chmod 777 /mnt/nfsshare
exportfs -i -o rw,no_root_squash *:/mnt/nfsshare
ip netns add netns_1
ip link add name veth_1_peer type veth peer veth_1 ifconfig veth_1_peer 11.11.0.254 up
ip link set veth_1 netns netns_1
ip netns exec netns_1 ifconfig veth_1 11.11.0.1
ip netns exec netns_1 /root/iptables -A OUTPUT -d 11.11.0.254 -p tcp \
--tcp-flags FIN FIN -j DROP
(note: In my environment, a DESTROY_CLIENTID operation is always sent
immediately, breaking the nfs tcp connection.)
ip netns exec netns_1 timeout -s 9 300 mount -t nfs -o proto=tcp,vers=4.1 \ 11.11.0.254:/mnt/nfsshare /mnt/nfs/netns_1
ip netns del netns_1
The reason here is that the tcp socket in netns_1 (nfs side) has been shutdown and closed (done in xs_destroy), but the FIN message (with ack) is discarded, and the nfsd side keeps sending retransmission messages. As a result, when the tcp sock in netns_1 processes the received message, it sends the message (FIN message) in the sending queue, and the tcp timer is re-established. When the network namespace is deleted, the net structure accessed by tcp's timer handler function causes problems.
To fix this problem, let's hold netns refcnt for the tcp kernel socket as done in other modules. This is an ugly hack which can easily be backported to earlier kernels. A proper fix which cleans up the interfaces will follow, but may not be so easy to backport.
--- net/sunrpc/svcsock.c | 4 ++++ net/sunrpc/xprtsock.c | 7 +++++++ 2 files changed, 11 insertions(+)
net/sunrpc/svcsock.c +4 -0
@@ -1562,6 +1562,10 @@ static struct svc_xprt *svc_create_socket(struct svc_serv *serv, newlen = error;if (protocol ==IPPROTO_TCP ) { +__netns_tracker_free (net, &sock->sk->ns_tracker, false); + sock->sk->sk_net_refcnt =1 ; +get_net_track (net, &sock->sk->ns_tracker,GFP_KERNEL ); +sock_inuse_add (net,1 );if ((error =kernel_listen (sock,64 )) <0 ) goto bummer; }
net/sunrpc/xprtsock.c +7 -0
@@ -1921,6 +1921,13 @@ static struct socket *xs_create_sock(struct rpc_xprt *xprt, goto out; } +if (protocol ==IPPROTO_TCP ) { +__netns_tracker_free (xprt->xprt_net, &sock->sk->ns_tracker, false); + sock->sk->sk_net_refcnt =1 ; +get_net_track (xprt->xprt_net, &sock->sk->ns_tracker,GFP_KERNEL ); +sock_inuse_add (xprt->xprt_net,1 ); + } + filp =sock_alloc_file (sock,O_NONBLOCK ,NULL );if (IS_ERR (filp))return ERR_CAST (filp);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 598/676 block, bfq: fix bfqq uaf in bfq_limit_depth()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Kuai <[email protected]>
[ Upstream commit e8b8344de3980709080d86c157d24e7de07d70ad ]
Set new allocated bfqq to bic or remove freed bfqq from bic are both protected by bfqd->lock, however bfq_limit_depth() is deferencing bfqq from bic without the lock, this can lead to UAF if the io_context is shared by multiple tasks.
For example, test bfq with io_uring can trigger following UAF in v6.6:
==================================================================
BUG: KASAN: slab-use-after-free in bfqq_group+0x15/0x50 Call Trace: <TASK> dump_stack_lvl+0x47/0x80 print_address_description.constprop.0+0x66/0x300 print_report+0x3e/0x70 kasan_report+0xb4/0xf0 bfqq_group+0x15/0x50 bfqq_request_over_limit+0x130/0x9a0 bfq_limit_depth+0x1b5/0x480 __blk_mq_alloc_requests+0x2b5/0xa00 blk_mq_get_new_requests+0x11d/0x1d0 blk_mq_submit_bio+0x286/0xb00 submit_bio_noacct_nocheck+0x331/0x400 __block_write_full_folio+0x3d0/0x640 writepage_cb+0x3b/0xc0 write_cache_pages+0x254/0x6c0 write_cache_pages+0x254/0x6c0 do_writepages+0x192/0x310 filemap_fdatawrite_wbc+0x95/0xc0 __filemap_fdatawrite_range+0x99/0xd0 filemap_write_and_wait_range.part.0+0x4d/0xa0 blkdev_read_iter+0xef/0x1e0 io_read+0x1b6/0x8a0 io_issue_sqe+0x87/0x300 io_wq_submit_work+0xeb/0x390 io_worker_handle_work+0x24d/0x550 io_wq_worker+0x27f/0x6c0 ret_from_fork_asm+0x1b/0x30 </TASK> Allocated by task 808602: kasan_save_stack+0x1e/0x40 kasan_set_track+0x21/0x30 __kasan_slab_alloc+0x83/0x90 kmem_cache_alloc_node+0x1b1/0x6d0 bfq_get_queue+0x138/0xfa0 bfq_get_bfqq_handle_split+0xe3/0x2c0 bfq_init_rq+0x196/0xbb0 bfq_insert_request.isra.0+0xb5/0x480 bfq_insert_requests+0x156/0x180 blk_mq_insert_request+0x15d/0x440 blk_mq_submit_bio+0x8a4/0xb00 submit_bio_noacct_nocheck+0x331/0x400 __blkdev_direct_IO_async+0x2dd/0x330 blkdev_write_iter+0x39a/0x450 io_write+0x22a/0x840 io_issue_sqe+0x87/0x300 io_wq_submit_work+0xeb/0x390 io_worker_handle_work+0x24d/0x550 io_wq_worker+0x27f/0x6c0 ret_from_fork+0x2d/0x50 ret_from_fork_asm+0x1b/0x30 Freed by task 808589: kasan_save_stack+0x1e/0x40 kasan_set_track+0x21/0x30 kasan_save_free_info+0x27/0x40 __kasan_slab_free+0x126/0x1b0 kmem_cache_free+0x10c/0x750 bfq_put_queue+0x2dd/0x770 __bfq_insert_request.isra.0+0x155/0x7a0 bfq_insert_request.isra.0+0x122/0x480 bfq_insert_requests+0x156/0x180 blk_mq_dispatch_plug_list+0x528/0x7e0 blk_mq_flush_plug_list.part.0+0xe5/0x590 __blk_flush_plug+0x3b/0x90 blk_finish_plug+0x40/0x60 do_writepages+0x19d/0x310 filemap_fdatawrite_wbc+0x95/0xc0 __filemap_fdatawrite_range+0x99/0xd0 filemap_write_and_wait_range.part.0+0x4d/0xa0 blkdev_read_iter+0xef/0x1e0 io_read+0x1b6/0x8a0 io_issue_sqe+0x87/0x300 io_wq_submit_work+0xeb/0x390 io_worker_handle_work+0x24d/0x550 io_wq_worker+0x27f/0x6c0 ret_from_fork+0x2d/0x50 ret_from_fork_asm+0x1b/0x30
Fix the problem by protecting bic_to_bfqq() with bfqd->lock.
--- block/bfq-iosched.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-)
block/bfq-iosched.c +24 -13
@@ -582,23 +582,31 @@ static struct request *bfq_choose_req(struct bfq_data *bfqd,#define BFQ_LIMIT_INLINE_DEPTH 16#ifdef CONFIG_BFQ_GROUP_IOSCHED -static bool bfqq_request_over_limit (struct bfq_queue *bfqq,int limit) +static bool bfqq_request_over_limit (struct bfq_data *bfqd, +struct bfq_io_cq *bic,blk_opf_t opf, +unsigned int act_idx,int limit) { -struct bfq_data *bfqd = bfqq->bfqd; -struct bfq_entity *entity = &bfqq->entity;struct bfq_entity *inline_entities[BFQ_LIMIT_INLINE_DEPTH ];struct bfq_entity **entities = inline_entities; -int depth, level, alloc_depth =BFQ_LIMIT_INLINE_DEPTH ; -int class_idx = bfqq->ioprio_class -1 ; +int alloc_depth =BFQ_LIMIT_INLINE_DEPTH ;struct bfq_sched_data *sched_data; +struct bfq_entity *entity; +struct bfq_queue *bfqq;unsigned long wsum;bool ret = false; - -if (!entity->on_st_or_in_serv) -return false; +int depth; +int level; retry:spin_lock_irq (&bfqd->lock); + bfqq =bic_to_bfqq (bic,op_is_sync (opf), act_idx); +if (!bfqq) + goto out; + + entity = &bfqq->entity; +if (!entity->on_st_or_in_serv) + goto out; +/* +1 for bfqq entity, root cgroup not included */ depth =bfqg_to_blkg (bfqq_group (bfqq))->blkcg->css.cgroup->level +1 ;if (depth > alloc_depth) {
@@ -643,7 +651,7 @@ static bool bfqq_request_over_limit(struct bfq_queue *bfqq, int limit)* class. */ wsum =0 ; -for (i =0 ; i <= class_idx; i++) { +for (i =0 ; i <= bfqq->ioprio_class -1 ; i++) { wsum = wsum *IOPRIO_BE_NR + sched_data->service_tree[i].wsum; }
@@ -666,7 +674,9 @@ static bool bfqq_request_over_limit(struct bfq_queue *bfqq, int limit) return ret; }#else -static bool bfqq_request_over_limit (struct bfq_queue *bfqq,int limit) +static bool bfqq_request_over_limit (struct bfq_data *bfqd, +struct bfq_io_cq *bic,blk_opf_t opf, +unsigned int act_idx,int limit) {return false; }
@@ -704,8 +714,9 @@ static void bfq_limit_depth(blk_opf_t opf, struct blk_mq_alloc_data *data) }for (act_idx =0 ; bic && act_idx < bfqd->num_actuators; act_idx++) { -struct bfq_queue *bfqq = -bic_to_bfqq (bic,op_is_sync (opf), act_idx); +/* Fast path to check if bfqq is already allocated. */ +if (!bic_to_bfqq (bic,op_is_sync (opf), act_idx)) +continue ;/* * Does queue (or any parent entity) exceed number of
@@ -713,7 +724,7 @@ static void bfq_limit_depth(blk_opf_t opf, struct blk_mq_alloc_data *data)* limit depth so that it cannot consume more * available requests and thus starve other entities. */ -if (bfqq &&bfqq_request_over_limit (bfqq, limit)) { +if (bfqq_request_over_limit (bfqd, bic, opf, act_idx, limit)) { depth =1 ;break ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 599/676 sh: intc: Fix use-after-free bug in register_intc_controller()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit 63e72e551942642c48456a4134975136cdcb9b3c ]
In the error handling for this function, d is freed without ever removing it from intc_list which would lead to a use after free. To fix this, let's only add it to the list after everything has succeeded.
--- drivers/sh/intc/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/sh/intc/core.c +1 -1
@@ -209,7 +209,6 @@ int __init register_intc_controller(struct intc_desc *desc) goto err0;INIT_LIST_HEAD (&d->list); -list_add_tail (&d->list, &intc_list);raw_spin_lock_init (&d->lock);INIT_RADIX_TREE (&d->tree,GFP_ATOMIC );
@@ -369,6 +368,7 @@ int __init register_intc_controller(struct intc_desc *desc) d->skip_suspend = desc->skip_syscore_suspend; +list_add_tail (&d->list, &intc_list); nr_intc_controllers++;return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 600/676 xfs: remove unknown compat feature check in superblock write validation
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Long Li <[email protected]>
[ Upstream commit 652f03db897ba24f9c4b269e254ccc6cc01ff1b7 ]
Compat features are new features that older kernels can safely ignore, allowing read-write mounts without issues. The current sb write validation implementation returns -EFSCORRUPTED for unknown compat features, preventing filesystem write operations and contradicting the feature's definition.
Additionally, if the mounted image is unclean, the log recovery may need to write to the superblock. Returning an error for unknown compat features during sb write validation can cause mount failures.
Although XFS currently does not use compat feature flags, this issue affects current kernels' ability to mount images that may use compat feature flags in the future.
Since superblock read validation already warns about unknown compat features, it's unnecessary to repeat this warning during write validation. Therefore, the relevant code in write validation is being removed.
--- fs/xfs/libxfs/xfs_sb.c | 7 ------- 1 file changed, 7 deletions(-)
fs/xfs/libxfs/xfs_sb.c +0 -7
@@ -260,13 +260,6 @@ xfs_validate_sb_write(* the kernel cannot support since we checked for unsupported bits in * the read verifier, which means that memory is corrupt. */ -if (xfs_sb_has_compat_feature (sbp,XFS_SB_FEAT_COMPAT_UNKNOWN )) { -xfs_warn (mp, -"Corruption detected in superblock compatible features (0x%x)!" , - (sbp->sb_features_compat &XFS_SB_FEAT_COMPAT_UNKNOWN )); -return -EFSCORRUPTED ; - } -if (!xfs_is_readonly (mp) &&xfs_sb_has_ro_compat_feature (sbp,XFS_SB_FEAT_RO_COMPAT_UNKNOWN )) { xfs_alert(mp,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 601/676 quota: flush quota_release_work upon quota writeback
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ojaswin Mujoo <[email protected]>
[ Upstream commit ac6f420291b3fee1113f21d612fa88b628afab5b ]
One of the paths quota writeback is called from is:
freeze_super()
sync_filesystem()
ext4_sync_fs()
dquot_writeback_dquots()Since we currently don't always flush the quota_release_work queue in this path, we can end up with the following race:
1. dquot are added to releasing_dquots list during regular operations.
2. FS Freeze starts, however, this does not flush the quota_release_work queue.
3. Freeze completes.
4. Kernel eventually tries to flush the workqueue while FS is frozen which hits a WARN_ON since transaction gets started during frozen state:
ext4_journal_check_start+0x28/0x110 [ext4] (unreliable) __ext4_journal_start_sb+0x64/0x1c0 [ext4] ext4_release_dquot+0x90/0x1d0 [ext4] quota_release_workfn+0x43c/0x4d0
Which is the following line:
WARN_ON(sb->s_writers.frozen == SB_FREEZE_COMPLETE);
Which ultimately results in generic/390 failing due to dmesg noise. This was detected on powerpc machine 15 cores.
To avoid this, make sure to flush the workqueue during dquot_writeback_dquots() so we dont have any pending workitems after freeze.
--- fs/quota/dquot.c | 2 ++ 1 file changed, 2 insertions(+)
fs/quota/dquot.c +2 -0
@@ -690,6 +690,8 @@ int dquot_writeback_dquots(struct super_block *sb, int type)WARN_ON_ONCE (!rwsem_is_locked (&sb->s_umount)); +flush_delayed_work ("a_release_work); +for (cnt =0 ; cnt <MAXQUOTAS ; cnt++) {if (type !=-1 && cnt != type)continue ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 602/676 btrfs: dont loop for nowait writes when checking for cross references
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit ed67f2a913a4f0fc505db29805c41dd07d3cb356 ]
When checking for delayed refs when verifying if there are cross references for a data extent, we stop if the path has nowait set and we can't try lock the delayed ref head's mutex, returning -EAGAIN with the goal of making a write fallback to a blocking context. However we ignore the -EAGAIN at btrfs_cross_ref_exist() when check_delayed_ref() returns it, and keep looping instead of immediately returning the -EAGAIN to the caller.
Fix this by not looping if we get -EAGAIN and we have a nowait path.
--- fs/btrfs/extent-tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/btrfs/extent-tree.c +1 -1
@@ -2401,7 +2401,7 @@ int btrfs_cross_ref_exist(struct btrfs_root *root, u64 objectid, u64 offset, goto out; ret =check_delayed_ref (root, path, objectid, offset, bytenr); - }while (ret == -EAGAIN ); + }while (ret == -EAGAIN && !path->nowait); out:btrfs_release_path (path);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 603/676 btrfs: add a sanity check for btrfs root in btrfs_search_slot()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lizhi Xu <[email protected]>
[ Upstream commit 3ed51857a50f530ac7a1482e069dfbd1298558d4 ]
Syzbot reports a null-ptr-deref in btrfs_search_slot().
The reproducer is using rescue=ibadroots, and the extent tree root is corrupted thus the extent tree is NULL.
When scrub tries to search the extent tree to gather the needed extent info, btrfs_search_slot() doesn't check if the target root is NULL or not, resulting the null-ptr-deref.
Add sanity check for btrfs root before using it in btrfs_search_slot().
--- fs/btrfs/ctree.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
fs/btrfs/ctree.c +5 -1
@@ -2157,7 +2157,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root, const struct btrfs_key *key, struct btrfs_path *p, int ins_len, int cow) { - struct btrfs_fs_info *fs_info = root->fs_info; + struct btrfs_fs_info *fs_info;struct extent_buffer *b;int slot;int ret;
@@ -2170,6 +2170,10 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root,int min_write_lock_level;int prev_cmp; +if (!root) +return -EINVAL ; + + fs_info = root->fs_info;might_sleep (); lowest_level = p->lowest_level;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 604/676 btrfs: ref-verify: fix use-after-free after invalid ref action
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit 7c4e39f9d2af4abaf82ca0e315d1fd340456620f ]
At btrfs_ref_tree_mod() after we successfully inserted the new ref entry (local variable 'ref') into the respective block entry's rbtree (local variable 'be'), if we find an unexpected action of BTRFS_DROP_DELAYED_REF, we error out and free the ref entry without removing it from the block entry's rbtree. Then in the error path of btrfs_ref_tree_mod() we call btrfs_free_ref_cache(), which iterates over all block entries and then calls free_block_entry() for each one, and there we will trigger a use-after-free when we are called against the block entry to which we added the freed ref entry to its rbtree, since the rbtree still points to the block entry, as we didn't remove it from the rbtree before freeing it in the error path at btrfs_ref_tree_mod(). Fix this by removing the new ref entry from the rbtree before freeing it.
Syzbot report this with the following stack traces:
BTRFS error (device loop0 state EA): Ref action 2, root 5, ref_root 0, parent 8564736, owner 0, offset 0, num_refs 18446744073709551615
__btrfs_mod_ref+0x7dd/0xac0 fs/btrfs/extent-tree.c:2523
update_ref_for_cow+0x9cd/0x11f0 fs/btrfs/ctree.c:512
btrfs_force_cow_block+0x9f6/0x1da0 fs/btrfs/ctree.c:594
btrfs_cow_block+0x35e/0xa40 fs/btrfs/ctree.c:754
btrfs_search_slot+0xbdd/0x30d0 fs/btrfs/ctree.c:2116
btrfs_insert_empty_items+0x9c/0x1a0 fs/btrfs/ctree.c:4314
btrfs_insert_empty_item fs/btrfs/ctree.h:669 [inline]
btrfs_insert_orphan_item+0x1f1/0x320 fs/btrfs/orphan.c:23
btrfs_orphan_add+0x6d/0x1a0 fs/btrfs/inode.c:3482
btrfs_unlink+0x267/0x350 fs/btrfs/inode.c:4293
vfs_unlink+0x365/0x650 fs/namei.c:4469
do_unlinkat+0x4ae/0x830 fs/namei.c:4533
__do_sys_unlinkat fs/namei.c:4576 [inline]
__se_sys_unlinkat fs/namei.c:4569 [inline]
__x64_sys_unlinkat+0xcc/0xf0 fs/namei.c:4569
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x77/0x7f
BTRFS error (device loop0 state EA): Ref action 1, root 5, ref_root 5, parent 0, owner 260, offset 0, num_refs 1
__btrfs_mod_ref+0x76b/0xac0 fs/btrfs/extent-tree.c:2521
update_ref_for_cow+0x96a/0x11f0
btrfs_force_cow_block+0x9f6/0x1da0 fs/btrfs/ctree.c:594
btrfs_cow_block+0x35e/0xa40 fs/btrfs/ctree.c:754
btrfs_search_slot+0xbdd/0x30d0 fs/btrfs/ctree.c:2116
btrfs_lookup_inode+0xdc/0x480 fs/btrfs/inode-item.c:411
__btrfs_update_delayed_inode+0x1e7/0xb90 fs/btrfs/delayed-inode.c:1030
btrfs_update_delayed_inode fs/btrfs/delayed-inode.c:1114 [inline]
__btrfs_commit_inode_delayed_items+0x2318/0x24a0 fs/btrfs/delayed-inode.c:1137
__btrfs_run_delayed_items+0x213/0x490 fs/btrfs/delayed-inode.c:1171
btrfs_commit_transaction+0x8a8/0x3740 fs/btrfs/transaction.c:2313
prepare_to_relocate+0x3c4/0x4c0 fs/btrfs/relocation.c:3586
relocate_block_group+0x16c/0xd40 fs/btrfs/relocation.c:3611
btrfs_relocate_block_group+0x77d/0xd90 fs/btrfs/relocation.c:4081
btrfs_relocate_chunk+0x12c/0x3b0 fs/btrfs/volumes.c:3377
__btrfs_balance+0x1b0f/0x26b0 fs/btrfs/volumes.c:4161
btrfs_balance+0xbdc/0x10c0 fs/btrfs/volumes.c:4538
BTRFS error (device loop0 state EA): Ref action 2, root 5, ref_root 0, parent 8564736, owner 0, offset 0, num_refs 18446744073709551615
__btrfs_mod_ref+0x7dd/0xac0 fs/btrfs/extent-tree.c:2523
update_ref_for_cow+0x9cd/0x11f0 fs/btrfs/ctree.c:512
btrfs_force_cow_block+0x9f6/0x1da0 fs/btrfs/ctree.c:594
btrfs_cow_block+0x35e/0xa40 fs/btrfs/ctree.c:754
btrfs_search_slot+0xbdd/0x30d0 fs/btrfs/ctree.c:2116
btrfs_lookup_inode+0xdc/0x480 fs/btrfs/inode-item.c:411
__btrfs_update_delayed_inode+0x1e7/0xb90 fs/btrfs/delayed-inode.c:1030
btrfs_update_delayed_inode fs/btrfs/delayed-inode.c:1114 [inline]
__btrfs_commit_inode_delayed_items+0x2318/0x24a0 fs/btrfs/delayed-inode.c:1137
__btrfs_run_delayed_items+0x213/0x490 fs/btrfs/delayed-inode.c:1171
btrfs_commit_transaction+0x8a8/0x3740 fs/btrfs/transaction.c:2313
prepare_to_relocate+0x3c4/0x4c0 fs/btrfs/relocation.c:3586
relocate_block_group+0x16c/0xd40 fs/btrfs/relocation.c:3611
btrfs_relocate_block_group+0x77d/0xd90 fs/btrfs/relocation.c:4081
btrfs_relocate_chunk+0x12c/0x3b0 fs/btrfs/volumes.c:3377
__btrfs_balance+0x1b0f/0x26b0 fs/btrfs/volumes.c:4161
btrfs_balance+0xbdc/0x10c0 fs/btrfs/volumes.c:4538
==================================================================
BUG: KASAN: slab-use-after-free in rb_first+0x69/0x70 lib/rbtree.c:473
Read of size 8 at addr ffff888042d1af38 by task syz.0.0/5329
CPU: 0 UID: 0 PID: 5329 Comm: syz.0.0 Not tainted 6.12.0-rc7-syzkaller #0
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:94 [inline]
dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120
print_address_description mm/kasan/report.c:377 [inline]
print_report+0x169/0x550 mm/kasan/report.c:488
kasan_report+0x143/0x180 mm/kasan/report.c:601
rb_first+0x69/0x70 lib/rbtree.c:473
free_block_entry+0x78/0x230 fs/btrfs/ref-verify.c:248
btrfs_free_ref_cache+0xa3/0x100 fs/btrfs/ref-verify.c:917
btrfs_ref_tree_mod+0x139f/0x15e0 fs/btrfs/ref-verify.c:898
btrfs_free_extent+0x33c/0x380 fs/btrfs/extent-tree.c:3544
__btrfs_mod_ref+0x7dd/0xac0 fs/btrfs/extent-tree.c:2523
update_ref_for_cow+0x9cd/0x11f0 fs/btrfs/ctree.c:512
btrfs_force_cow_block+0x9f6/0x1da0 fs/btrfs/ctree.c:594
btrfs_cow_block+0x35e/0xa40 fs/btrfs/ctree.c:754
btrfs_search_slot+0xbdd/0x30d0 fs/btrfs/ctree.c:2116
btrfs_lookup_inode+0xdc/0x480 fs/btrfs/inode-item.c:411
__btrfs_update_delayed_inode+0x1e7/0xb90 fs/btrfs/delayed-inode.c:1030
btrfs_update_delayed_inode fs/btrfs/delayed-inode.c:1114 [inline]
__btrfs_commit_inode_delayed_items+0x2318/0x24a0 fs/btrfs/delayed-inode.c:1137
__btrfs_run_delayed_items+0x213/0x490 fs/btrfs/delayed-inode.c:1171
btrfs_commit_transaction+0x8a8/0x3740 fs/btrfs/transaction.c:2313
prepare_to_relocate+0x3c4/0x4c0 fs/btrfs/relocation.c:3586
relocate_block_group+0x16c/0xd40 fs/btrfs/relocation.c:3611
btrfs_relocate_block_group+0x77d/0xd90 fs/btrfs/relocation.c:4081
btrfs_relocate_chunk+0x12c/0x3b0 fs/btrfs/volumes.c:3377
__btrfs_balance+0x1b0f/0x26b0 fs/btrfs/volumes.c:4161
btrfs_balance+0xbdc/0x10c0 fs/btrfs/volumes.c:4538
btrfs_ioctl_balance+0x493/0x7c0 fs/btrfs/ioctl.c:3673
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:907 [inline]
__se_sys_ioctl+0xf9/0x170 fs/ioctl.c:893
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f996df7e719
RSP: 002b:00007f996ede7038 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007f996e135f80 RCX: 00007f996df7e719
RDX: 0000000020000180 RSI: 00000000c4009420 RDI: 0000000000000004
RBP: 00007f996dff139e R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 0000000000000000 R14: 00007f996e135f80 R15: 00007fff79f32e68
</TASK>
Allocated by task 5329:
kasan_save_stack mm/kasan/common.c:47 [inline]
kasan_save_track+0x3f/0x80 mm/kasan/common.c:68
poison_kmalloc_redzone mm/kasan/common.c:377 [inline]
__kasan_kmalloc+0x98/0xb0 mm/kasan/common.c:394
kasan_kmalloc include/linux/kasan.h:257 [inline]
__kmalloc_cache_noprof+0x19c/0x2c0 mm/slub.c:4295
kmalloc_noprof include/linux/slab.h:878 [inline]
kzalloc_noprof include/linux/slab.h:1014 [inline]
btrfs_ref_tree_mod+0x264/0x15e0 fs/btrfs/ref-verify.c:701
btrfs_free_extent+0x33c/0x380 fs/btrfs/extent-tree.c:3544
__btrfs_mod_ref+0x7dd/0xac0 fs/btrfs/extent-tree.c:2523
update_ref_for_cow+0x9cd/0x11f0 fs/btrfs/ctree.c:512
btrfs_force_cow_block+0x9f6/0x1da0 fs/btrfs/ctree.c:594
btrfs_cow_block+0x35e/0xa40 fs/btrfs/ctree.c:754
btrfs_search_slot+0xbdd/0x30d0 fs/btrfs/ctree.c:2116
btrfs_lookup_inode+0xdc/0x480 fs/btrfs/inode-item.c:411
__btrfs_update_delayed_inode+0x1e7/0xb90 fs/btrfs/delayed-inode.c:1030
btrfs_update_delayed_inode fs/btrfs/delayed-inode.c:1114 [inline]
__btrfs_commit_inode_delayed_items+0x2318/0x24a0 fs/btrfs/delayed-inode.c:1137
__btrfs_run_delayed_items+0x213/0x490 fs/btrfs/delayed-inode.c:1171
btrfs_commit_transaction+0x8a8/0x3740 fs/btrfs/transaction.c:2313
prepare_to_relocate+0x3c4/0x4c0 fs/btrfs/relocation.c:3586
relocate_block_group+0x16c/0xd40 fs/btrfs/relocation.c:3611
btrfs_relocate_block_group+0x77d/0xd90 fs/btrfs/relocation.c:4081
btrfs_relocate_chunk+0x12c/0x3b0 fs/btrfs/volumes.c:3377
__btrfs_balance+0x1b0f/0x26b0 fs/btrfs/volumes.c:4161
btrfs_balance+0xbdc/0x10c0 fs/btrfs/volumes.c:4538
btrfs_ioctl_balance+0x493/0x7c0 fs/btrfs/ioctl.c:3673
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:907 [inline]
__se_sys_ioctl+0xf9/0x170 fs/ioctl.c:893
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Freed by task 5329:
kasan_save_stack mm/kasan/common.c:47 [inline]
kasan_save_track+0x3f/0x80 mm/kasan/common.c:68
kasan_save_free_info+0x40/0x50 mm/kasan/generic.c:579
poison_slab_object mm/kasan/common.c:247 [inline]
__kasan_slab_free+0x59/0x70 mm/kasan/common.c:264
kasan_slab_free include/linux/kasan.h:230 [inline]
slab_free_hook mm/slub.c:2342 [inline]
slab_free mm/slub.c:4579 [inline]
kfree+0x1a0/0x440 mm/slub.c:4727
btrfs_ref_tree_mod+0x136c/0x15e0
btrfs_free_extent+0x33c/0x380 fs/btrfs/extent-tree.c:3544
__btrfs_mod_ref+0x7dd/0xac0 fs/btrfs/extent-tree.c:2523
update_ref_for_cow+0x9cd/0x11f0 fs/btrfs/ctree.c:512
btrfs_force_cow_block+0x9f6/0x1da0 fs/btrfs/ctree.c:594
btrfs_cow_block+0x35e/0xa40 fs/btrfs/ctree.c:754
btrfs_search_slot+0xbdd/0x30d0 fs/btrfs/ctree.c:2116
btrfs_lookup_inode+0xdc/0x480 fs/btrfs/inode-item.c:411
__btrfs_update_delayed_inode+0x1e7/0xb90 fs/btrfs/delayed-inode.c:1030
btrfs_update_delayed_inode fs/btrfs/delayed-inode.c:1114 [inline]
__btrfs_commit_inode_delayed_items+0x2318/0x24a0 fs/btrfs/delayed-inode.c:1137
__btrfs_run_delayed_items+0x213/0x490 fs/btrfs/delayed-inode.c:1171
btrfs_commit_transaction+0x8a8/0x3740 fs/btrfs/transaction.c:2313
prepare_to_relocate+0x3c4/0x4c0 fs/btrfs/relocation.c:3586
relocate_block_group+0x16c/0xd40 fs/btrfs/relocation.c:3611
btrfs_relocate_block_group+0x77d/0xd90 fs/btrfs/relocation.c:4081
btrfs_relocate_chunk+0x12c/0x3b0 fs/btrfs/volumes.c:3377
__btrfs_balance+0x1b0f/0x26b0 fs/btrfs/volumes.c:4161
btrfs_balance+0xbdc/0x10c0 fs/btrfs/volumes.c:4538
btrfs_ioctl_balance+0x493/0x7c0 fs/btrfs/ioctl.c:3673
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:907 [inline]
__se_sys_ioctl+0xf9/0x170 fs/ioctl.c:893
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x77/0x7f
The buggy address belongs to the object at ffff888042d1af00
which belongs to the cache kmalloc-64 of size 64
The buggy address is located 56 bytes inside of
freed 64-byte region [ffff888042d1af00, ffff888042d1af40)
The buggy address belongs to the physical page:
page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x42d1a
anon flags: 0x4fff00000000000(node=1|zone=1|lastcpupid=0x7ff)
page_type: f5(slab)
raw: 04fff00000000000 ffff88801ac418c0 0000000000000000 dead000000000001
raw: 0000000000000000 0000000000200020 00000001f5000000 0000000000000000
page dumped because: kasan: bad access detected
page_owner tracks the page as allocated
page last allocated via order 0, migratetype Unmovable, gfp_mask 0x52c40(GFP_NOFS|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP), pid 5055, tgid 5055 (dhcpcd-run-hook), ts 40377240074, free_ts 40376848335
set_page_owner include/linux/page_owner.h:32 [inline]
post_alloc_hook+0x1f3/0x230 mm/page_alloc.c:1541
prep_new_page mm/page_alloc.c:1549 [inline]
get_page_from_freelist+0x3649/0x3790 mm/page_alloc.c:3459
__alloc_pages_noprof+0x292/0x710 mm/page_alloc.c:4735
alloc_pages_mpol_noprof+0x3e8/0x680 mm/mempolicy.c:2265
alloc_slab_page+0x6a/0x140 mm/slub.c:2412
allocate_slab+0x5a/0x2f0 mm/slub.c:2578
new_slab mm/slub.c:2631 [inline]
___slab_alloc+0xcd1/0x14b0 mm/slub.c:3818
__slab_alloc+0x58/0xa0 mm/slub.c:3908
__slab_alloc_node mm/slub.c:3961 [inline]
slab_alloc_node mm/slub.c:4122 [inline]
__do_kmalloc_node mm/slub.c:4263 [inline]
__kmalloc_noprof+0x25a/0x400 mm/slub.c:4276
kmalloc_noprof include/linux/slab.h:882 [inline]
kzalloc_noprof include/linux/slab.h:1014 [inline]
tomoyo_encode2 security/tomoyo/realpath.c:45 [inline]
tomoyo_encode+0x26f/0x540 security/tomoyo/realpath.c:80
tomoyo_realpath_from_path+0x59e/0x5e0 security/tomoyo/realpath.c:283
tomoyo_get_realpath security/tomoyo/file.c:151 [inline]
tomoyo_check_open_permission+0x255/0x500 security/tomoyo/file.c:771
security_file_open+0x777/0x990 security/security.c:3109
do_dentry_open+0x369/0x1460 fs/open.c:945
vfs_open+0x3e/0x330 fs/open.c:1088
do_open fs/namei.c:3774 [inline]
path_openat+0x2c84/0x3590 fs/namei.c:3933
page last free pid 5055 tgid 5055 stack trace:
reset_page_owner include/linux/page_owner.h:25 [inline]
free_pages_prepare mm/page_alloc.c:1112 [inline]
free_unref_page+0xcfb/0xf20 mm/page_alloc.c:2642
free_pipe_info+0x300/0x390 fs/pipe.c:860
put_pipe_info fs/pipe.c:719 [inline]
pipe_release+0x245/0x320 fs/pipe.c:742
__fput+0x23f/0x880 fs/file_table.c:431
__do_sys_close fs/open.c:1567 [inline]
__se_sys_close fs/open.c:1552 [inline]
__x64_sys_close+0x7f/0x110 fs/open.c:1552
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Memory state around the buggy address:
ffff888042d1ae00: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
ffff888042d1ae80: 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc fc
>ffff888042d1af00: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
^
ffff888042d1af80: 00 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc
ffff888042d1b000: 00 00 00 00 00 fc fc 00 00 00 00 00 fc fc 00 00--- fs/btrfs/ref-verify.c | 1 + 1 file changed, 1 insertion(+)
fs/btrfs/ref-verify.c +1 -0
@@ -849,6 +849,7 @@ int btrfs_ref_tree_mod(struct btrfs_fs_info *fs_info, "dropping a ref for a root that doesn't have a ref on the block");dump_block_entry (fs_info, be);dump_ref_action (fs_info, ra); +rb_erase (&ref->node, &be->refs);kfree (ref);kfree (ra); goto out_unlock;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 605/676 md/md-bitmap: Add missing destroy_work_on_stack()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuan Can <[email protected]>
commit 6012169e8aae9c0eda38bbedcd7a1540a81220ae upstream.
This commit add missed destroy_work_on_stack() operations for unplug_work.work in bitmap_unplug_async().
--- drivers/md/md-bitmap.c | 1 + 1 file changed, 1 insertion(+)
drivers/md/md-bitmap.c +1 -0
@@ -1089,6 +1089,7 @@ void md_bitmap_unplug_async(struct bitmaqueue_work (md_bitmap_wq, &unplug_work.work);wait_for_completion (&done); +destroy_work_on_stack (&unplug_work.work); }EXPORT_SYMBOL (md_bitmap_unplug_async);
Greg Kroah-Hartman
maintainerPATCH 606/676 arm64: dts: allwinner: pinephone: Add mount matrix to accelerometer
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dragan Simic <[email protected]>
commit 2496b2aaacf137250f4ca449f465e2cadaabb0e8 upstream.
The way InvenSense MPU-6050 accelerometer is mounted on the user-facing side of the Pine64 PinePhone mainboard, which makes it rotated 90 degrees counter- clockwise, [1] requires the accelerometer's x- and y-axis to be swapped, and the direction of the accelerometer's y-axis to be inverted.
Rectify this by adding a mount-matrix to the accelerometer definition in the Pine64 PinePhone dtsi file.
--- arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi | 3 +++ 1 file changed, 3 insertions(+)
arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi +3 -0
@@ -202,6 +202,9 @@ interrupts = <7 5 IRQ_TYPE_EDGE_RISING>; /* PH5 */ vdd-supply = <®_dldo1>; vddio-supply = <®_dldo1>; + mount-matrix = "0", "1", "0", + "-1", "0", "0", + "0", "0", "1"; }; };
Greg Kroah-Hartman
maintainerPATCH 607/676 arm64: dts: freescale: imx8mm-verdin: Fix SD regulator startup delay
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Francesco Dolcini <[email protected]>
commit 0ca7699c376743b633b6419a42888dba386d5351 upstream.
The power switch used to power the SD card interface might have more than 2ms turn-on time, increase the startup delay to 20ms to prevent failures.
--- arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi +1 -1
@@ -145,7 +145,7 @@ regulator-max-microvolt = <3300000>; regulator-min-microvolt = <3300000>; regulator-name = "+V3.3_SD"; - startup-delay-us = <2000>; + startup-delay-us = <20000>; }; reserved-memory {
Greg Kroah-Hartman
maintainerPATCH 608/676 arm64: dts: ti: k3-am62-verdin: Fix SD regulator startup delay
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Francesco Dolcini <[email protected]>
commit 2213ca51998fef61d3df4ca156054cdcc37c42b8 upstream.
The power switch used to power the SD card interface might have more than 2ms turn-on time, increase the startup delay to 20ms to prevent failures.
--- arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi +1 -1
@@ -134,7 +134,7 @@ regulator-max-microvolt = <3300000>; regulator-min-microvolt = <3300000>; regulator-name = "+V3.3_SD"; - startup-delay-us = <2000>; + startup-delay-us = <20000>; }; reg_sdhc1_vqmmc: regulator-sdhci1-vqmmc {
Greg Kroah-Hartman
maintainerPATCH 609/676 media: amphion: Set video drvdata before register video device
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Qian <[email protected]>
commit 8cbb1a7bd5973b57898b26eb804fe44af440bb63 upstream.
The video drvdata should be set before the video device is registered, otherwise video_drvdata() may return NULL in the open() file ops, and led to oops.
--- drivers/media/platform/amphion/vpu_v4l2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/platform/amphion/vpu_v4l2.c +1 -1
@@ -825,6 +825,7 @@ int vpu_add_func(struct vpu_dev *vpu, st vfd->fops =vdec_get_fops (); vfd->ioctl_ops =vdec_get_ioctl_ops (); } +video_set_drvdata (vfd, vpu); ret =video_register_device (vfd,VFL_TYPE_VIDEO ,-1 );if (ret) {
@@ -832,7 +833,6 @@ int vpu_add_func(struct vpu_dev *vpu, stv4l2_m2m_release (func->m2m_dev);return ret; } -video_set_drvdata (vfd, vpu); func->vfd = vfd; ret =v4l2_m2m_register_media_controller (func->m2m_dev, func->vfd, func->function);
Greg Kroah-Hartman
maintainerPATCH 610/676 media: imx-jpeg: Set video drvdata before register video device
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Qian <[email protected]>
commit d2b7ecc26bd5406d5ba927be1748aa99c568696c upstream.
The video drvdata should be set before the video device is registered, otherwise video_drvdata() may return NULL in the open() file ops, and led to oops.
--- drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +1 -1
@@ -2837,6 +2837,7 @@ static int mxc_jpeg_probe(struct platfor jpeg->dec_vdev->vfl_dir =VFL_DIR_M2M ; jpeg->dec_vdev->device_caps =V4L2_CAP_STREAMING |V4L2_CAP_VIDEO_M2M_MPLANE ; +video_set_drvdata (jpeg->dec_vdev, jpeg);if (mode ==MXC_JPEG_ENCODE ) {v4l2_disable_ioctl (jpeg->dec_vdev,VIDIOC_DECODER_CMD );v4l2_disable_ioctl (jpeg->dec_vdev,VIDIOC_TRY_DECODER_CMD );
@@ -2849,7 +2850,6 @@ static int mxc_jpeg_probe(struct platfordev_err (dev,"failed to register video device\n" ); goto err_vdev_register; } -video_set_drvdata (jpeg->dec_vdev, jpeg);if (mode ==MXC_JPEG_ENCODE ) v4l2_info(&jpeg->v4l2_dev, "encoder device registered as /dev/video%d (%d,%d)\n",
Greg Kroah-Hartman
maintainerPATCH 611/676 media: mtk-jpeg: Fix null-ptr-deref during unload module
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guoqing Jiang <[email protected]>
commit 17af2b39daf12870cac61ffc360e62bc35798afb upstream.
The workqueue should be destroyed in mtk_jpeg_core.c since commit 09aea13ecf6f ("media: mtk-jpeg: refactor some variables"), otherwise the below calltrace can be easily triggered.
[ 677.862514] Unable to handle kernel paging request at virtual address dfff800000000023 [ 677.863633] KASAN: null-ptr-deref in range [0x0000000000000118-0x000000000000011f] ... [ 677.879654] CPU: 6 PID: 1071 Comm: modprobe Tainted: G O 6.8.12-mtk+gfa1a78e5d24b+ #17 ... [ 677.882838] pc : destroy_workqueue+0x3c/0x770 [ 677.883413] lr : mtk_jpegdec_destroy_workqueue+0x70/0x88 [mtk_jpeg_dec_hw] [ 677.884314] sp : ffff80008ad974f0 [ 677.884744] x29: ffff80008ad974f0 x28: ffff0000d7115580 x27: ffff0000dd691070 [ 677.885669] x26: ffff0000dd691408 x25: ffff8000844af3e0 x24: ffff80008ad97690 [ 677.886592] x23: ffff0000e051d400 x22: ffff0000dd691010 x21: dfff800000000000 [ 677.887515] x20: 0000000000000000 x19: 0000000000000000 x18: ffff800085397ac0 [ 677.888438] x17: 0000000000000000 x16: ffff8000801b87c8 x15: 1ffff000115b2e10 [ 677.889361] x14: 00000000f1f1f1f1 x13: 0000000000000000 x12: ffff7000115b2e4d [ 677.890285] x11: 1ffff000115b2e4c x10: ffff7000115b2e4c x9 : ffff80000aa43e90 [ 677.891208] x8 : 00008fffeea4d1b4 x7 : ffff80008ad97267 x6 : 0000000000000001 [ 677.892131] x5 : ffff80008ad97260 x4 : ffff7000115b2e4d x3 : 0000000000000000 [ 677.893054] x2 : 0000000000000023 x1 : dfff800000000000 x0 : 0000000000000118 [ 677.893977] Call trace: [ 677.894297] destroy_workqueue+0x3c/0x770 [ 677.894826] mtk_jpegdec_destroy_workqueue+0x70/0x88 [mtk_jpeg_dec_hw] [ 677.895677] devm_action_release+0x50/0x90 [ 677.896211] release_nodes+0xe8/0x170 [ 677.896688] devres_release_all+0xf8/0x178 [ 677.897219] device_unbind_cleanup+0x24/0x170 [ 677.897785] device_release_driver_internal+0x35c/0x480 [ 677.898461] device_release_driver+0x20/0x38 ... [ 677.912665] ---[ end trace 0000000000000000 ]---
--- drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c | 10 ++++++++++ drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c | 11 ----------- 2 files changed, 10 insertions(+), 11 deletions(-)
drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +10 -0
@@ -1294,6 +1294,11 @@ static int mtk_jpeg_single_core_init(strreturn 0 ; } +static void mtk_jpeg_destroy_workqueue (void *data) +{ +destroy_workqueue (data); +} +static int mtk_jpeg_probe (struct platform_device *pdev) {struct mtk_jpeg_dev *jpeg;
@@ -1338,6 +1343,11 @@ static int mtk_jpeg_probe(struct platfor | WQ_FREEZABLE);if (!jpeg->workqueue)return -EINVAL ; + ret =devm_add_action_or_reset (&pdev->dev, + mtk_jpeg_destroy_workqueue, + jpeg->workqueue); +if (ret) +return ret; } ret =v4l2_device_register (&pdev->dev, &jpeg->v4l2_dev);
drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c +0 -11
@@ -578,11 +578,6 @@ static int mtk_jpegdec_hw_init_irq(strucreturn 0 ; } -static void mtk_jpegdec_destroy_workqueue (void *data) -{ -destroy_workqueue (data); -} -static int mtk_jpegdec_hw_probe (struct platform_device *pdev) {struct mtk_jpegdec_clk *jpegdec_clk;
@@ -606,12 +601,6 @@ static int mtk_jpegdec_hw_probe(struct p dev->plat_dev = pdev; dev->dev = &pdev->dev; - ret =devm_add_action_or_reset (&pdev->dev, - mtk_jpegdec_destroy_workqueue, - master_dev->workqueue); -if (ret) -return ret; -spin_lock_init (&dev->hw_lock); dev->hw_state =MTK_JPEG_HW_IDLE ;
Greg Kroah-Hartman
maintainerPATCH 612/676 media: i2c: dw9768: Fix pm_runtime_set_suspended() with runtime pm enabled
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
commit d6594d50761728d09f23238cf9c368bab6260ef3 upstream.
It is not valid to call pm_runtime_set_suspended() and pm_runtime_set_active() for devices with runtime PM enabled because it returns -EAGAIN if it is enabled already and working. So, adjust the order to fix it.
--- drivers/media/i2c/dw9768.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/media/i2c/dw9768.c +5 -5
@@ -476,10 +476,9 @@ static int dw9768_probe(struct i2c_clien* to be powered on in an ACPI system. Similarly for power off in * remove. */ -pm_runtime_enable (dev); full_power = (is_acpi_node (dev_fwnode (dev)) &&acpi_dev_state_d0 (dev)) || - (is_of_node (dev_fwnode (dev)) && !pm_runtime_enabled (dev)); + (is_of_node (dev_fwnode (dev)) && !IS_ENABLED (CONFIG_PM ));if (full_power) { ret =dw9768_runtime_resume (dev);if (ret <0 ) {
@@ -489,6 +488,7 @@ static int dw9768_probe(struct i2c_clienpm_runtime_set_active (dev); } +pm_runtime_enable (dev); ret =v4l2_async_register_subdev (&dw9768->sd);if (ret <0 ) {dev_err (dev,"failed to register V4L2 subdev: %d" , ret);
@@ -500,12 +500,12 @@ static int dw9768_probe(struct i2c_clienreturn 0 ; err_power_off: +pm_runtime_disable (dev);if (full_power) {dw9768_runtime_suspend (dev);pm_runtime_set_suspended (dev); } err_clean_entity: -pm_runtime_disable (dev);media_entity_cleanup (&dw9768->sd.entity); err_free_handler:v4l2_ctrl_handler_free (&dw9768->ctrls);
@@ -522,12 +522,12 @@ static void dw9768_remove(struct i2c_cliv4l2_async_unregister_subdev (&dw9768->sd);v4l2_ctrl_handler_free (&dw9768->ctrls);media_entity_cleanup (&dw9768->sd.entity); +pm_runtime_disable (dev);if ((is_acpi_node (dev_fwnode (dev)) &&acpi_dev_state_d0 (dev)) || - (is_of_node (dev_fwnode (dev)) && !pm_runtime_enabled (dev))) { + (is_of_node (dev_fwnode (dev)) && !IS_ENABLED (CONFIG_PM ))) {dw9768_runtime_suspend (dev);pm_runtime_set_suspended (dev); } -pm_runtime_disable (dev); }static const struct of_device_id dw9768_of_table[] = {
Greg Kroah-Hartman
maintainerPATCH 613/676 arm64: dts: freescale: imx8mp-verdin: Fix SD regulator startup delay
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Francesco Dolcini <[email protected]>
commit 6c5789c9d2c06968532243daa235f6ff809ad71e upstream.
The power switch used to power the SD card interface might have more than 2ms turn-on time, increase the startup delay to 20ms to prevent failures.
--- arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi +1 -1
@@ -134,7 +134,7 @@ regulator-max-microvolt = <3300000>; regulator-min-microvolt = <3300000>; regulator-name = "+V3.3_SD"; - startup-delay-us = <2000>; + startup-delay-us = <20000>; }; reserved-memory {
Greg Kroah-Hartman
maintainerPATCH 614/676 media: i2c: tc358743: Fix crash in the probe error path when using polling
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Shiyan <[email protected]>
commit 869f38ae07f7df829da4951c3d1f7a2be09c2e9a upstream.
If an error occurs in the probe() function, we should remove the polling timer that was alarmed earlier, otherwise the timer is called with arguments that are already freed, which results in a crash.
------------[ cut here ]------------ WARNING: CPU: 3 PID: 0 at kernel/time/timer.c:1830 __run_timers+0x244/0x268 Modules linked in: CPU: 3 UID: 0 PID: 0 Comm: swapper/3 Not tainted 6.11.0 #226 Hardware name: Diasom DS-RK3568-SOM-EVB (DT) pstate: 804000c9 (Nzcv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : __run_timers+0x244/0x268 lr : __run_timers+0x1d4/0x268
sp : ffffff80eff2baf0
x29: ffffff80eff2bb50 x28: 7fffffffffffffff x27: ffffff80eff2bb00
x26: ffffffc080f669c0 x25: ffffff80efef6bf0 x24: ffffff80eff2bb00
x23: 0000000000000000 x22: dead000000000122 x21: 0000000000000000
x20: ffffff80efef6b80 x19: ffffff80041c8bf8 x18: ffffffffffffffff
x17: ffffffc06f146000 x16: ffffff80eff27dc0 x15: 000000000000003e
x14: 0000000000000000 x13: 00000000000054da x12: 0000000000000000
x11: 00000000000639c0 x10: 000000000000000c x9 : 0000000000000009 x8 : ffffff80eff2cb40 x7 : ffffff80eff2cb40 x6 : ffffff8002bee480 x5 : ffffffc080cb2220 x4 : ffffffc080cb2150 x3 : 00000000000f4240 x2 : 0000000000000102 x1 : ffffff80eff2bb00 x0 : ffffff80041c8bf0
Call trace: __run_timers+0x244/0x268 timer_expire_remote+0x50/0x68 tmigr_handle_remote+0x388/0x39c run_timer_softirq+0x38/0x44 handle_softirqs+0x138/0x298 __do_softirq+0x14/0x20 ____do_softirq+0x10/0x1c call_on_irq_stack+0x24/0x4c do_softirq_own_stack+0x1c/0x2c irq_exit_rcu+0x9c/0xcc el1_interrupt+0x48/0xc0 el1h_64_irq_handler+0x18/0x24 el1h_64_irq+0x7c/0x80 default_idle_call+0x34/0x68 do_idle+0x23c/0x294 cpu_startup_entry+0x38/0x3c secondary_start_kernel+0x128/0x160 __secondary_switched+0xb8/0xbc ---[ end trace 0000000000000000 ]---
--- drivers/media/i2c/tc358743.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/media/i2c/tc358743.c +3 -1
@@ -2159,8 +2159,10 @@ static int tc358743_probe(struct i2c_cli err_work_queues:cec_unregister_adapter (state->cec_adap); -if (!state->i2c_client->irq) +if (!state->i2c_client->irq) { +del_timer (&state->timer);flush_work (&state->work_i2c_poll); + }cancel_delayed_work (&state->delayed_work_enable_hotplug);mutex_destroy (&state->confctl_mutex); err_hdl:
Greg Kroah-Hartman
maintainerPATCH 615/676 media: imx-jpeg: Ensure power suppliers be suspended before detach them
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Qian <[email protected]>
commit fd0af4cd35da0eb550ef682b71cda70a4e36f6b9 upstream.
The power suppliers are always requested to suspend asynchronously, dev_pm_domain_detach() requires the caller to ensure proper synchronization of this function with power management callbacks. otherwise the detach may led to kernel panic, like below:
[ 1457.107934] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000040 [ 1457.116777] Mem abort info: [ 1457.119589] ESR = 0x0000000096000004 [ 1457.123358] EC = 0x25: DABT (current EL), IL = 32 bits [ 1457.128692] SET = 0, FnV = 0 [ 1457.131764] EA = 0, S1PTW = 0 [ 1457.134920] FSC = 0x04: level 0 translation fault [ 1457.139812] Data abort info: [ 1457.142707] ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000 [ 1457.148196] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 [ 1457.153256] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 [ 1457.158563] user pgtable: 4k pages, 48-bit VAs, pgdp=00000001138b6000 [ 1457.165000] [0000000000000040] pgd=0000000000000000, p4d=0000000000000000 [ 1457.171792] Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP [ 1457.178045] Modules linked in: v4l2_jpeg wave6_vpu_ctrl(-) [last unloaded: mxc_jpeg_encdec] [ 1457.186383] CPU: 0 PID: 51938 Comm: kworker/0:3 Not tainted 6.6.36-gd23d64eea511 #66 [ 1457.194112] Hardware name: NXP i.MX95 19X19 board (DT) [ 1457.199236] Workqueue: pm pm_runtime_work [ 1457.203247] pstate: 60400009 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 1457.210188] pc : genpd_runtime_suspend+0x20/0x290 [ 1457.214886] lr : __rpm_callback+0x48/0x1d8 [ 1457.218968] sp : ffff80008250bc50 [ 1457.222270] x29: ffff80008250bc50 x28: 0000000000000000 x27: 0000000000000000 [ 1457.229394] x26: 0000000000000000 x25: 0000000000000008 x24: 00000000000f4240 [ 1457.236518] x23: 0000000000000000 x22: ffff00008590f0e4 x21: 0000000000000008 [ 1457.243642] x20: ffff80008099c434 x19: ffff00008590f000 x18: ffffffffffffffff [ 1457.250766] x17: 5300326563697665 x16: 645f676e696c6f6f x15: 63343a6d726f6674 [ 1457.257890] x14: 0000000000000004 x13: 00000000000003a4 x12: 0000000000000002 [ 1457.265014] x11: 0000000000000000 x10: 0000000000000a60 x9 : ffff80008250bbb0 [ 1457.272138] x8 : ffff000092937200 x7 : ffff0003fdf6af80 x6 : 0000000000000000 [ 1457.279262] x5 : 00000000410fd050 x4 : 0000000000200000 x3 : 0000000000000000 [ 1457.286386] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff00008590f000 [ 1457.293510] Call trace: [ 1457.295946] genpd_runtime_suspend+0x20/0x290 [ 1457.300296] __rpm_callback+0x48/0x1d8 [ 1457.304038] rpm_callback+0x6c/0x78 [ 1457.307515] rpm_suspend+0x10c/0x570 [ 1457.311077] pm_runtime_work+0xc4/0xc8 [ 1457.314813] process_one_work+0x138/0x248 [ 1457.318816] worker_thread+0x320/0x438 [ 1457.322552] kthread+0x110/0x114 [ 1457.325767] ret_from_fork+0x10/0x20
--- drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +2 -0
@@ -2674,6 +2674,8 @@ static void mxc_jpeg_detach_pm_domains(sint i;for (i =0 ; i < jpeg->num_domains; i++) { +if (jpeg->pd_dev[i] && !pm_runtime_suspended (jpeg->pd_dev[i])) +pm_runtime_force_suspend (jpeg->pd_dev[i]);if (jpeg->pd_link[i] && !IS_ERR (jpeg->pd_link[i]))device_link_del (jpeg->pd_link[i]);if (jpeg->pd_dev[i] && !IS_ERR (jpeg->pd_dev[i]))
Greg Kroah-Hartman
maintainerPATCH 616/676 media: verisilicon: av1: Fix reference video buffer pointer assignment
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Gaignard <[email protected]>
commit 672f24ed6ebcd986688c6674a6d994a265fefc25 upstream.
Always get new destination buffer for reference frame because nothing garantees the one set previously is still valid or unused.
Fixes this chromium test suite:
https://chromium.googlesource.com/chromium/src/media/+/refs/heads/main/test/data/test-25fps.av1.ivf
--- drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c +1 -2
@@ -161,8 +161,7 @@ static int rockchip_vpu981_av1_dec_frame av1_dec->frame_refs[i].timestamp = timestamp; av1_dec->frame_refs[i].frame_type = frame->frame_type; av1_dec->frame_refs[i].order_hint = frame->order_hint; -if (!av1_dec->frame_refs[i].vb2_ref) - av1_dec->frame_refs[i].vb2_ref =hantro_get_dst_buf (ctx); + av1_dec->frame_refs[i].vb2_ref =hantro_get_dst_buf (ctx);for (j =0 ; j <V4L2_AV1_TOTAL_REFS_PER_FRAME ; j++) av1_dec->frame_refs[i].order_hints[j] = frame->order_hints[j];
Greg Kroah-Hartman
maintainerPATCH 617/676 media: ts2020: fix null-ptr-deref in ts2020_probe()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Zetao <[email protected]>
commit 4a058b34b52ed3feb1f3ff6fd26aefeeeed20cba upstream.
KASAN reported a null-ptr-deref issue when executing the following command:
# echo ts2020 0x20 > /sys/bus/i2c/devices/i2c-0/new_device
KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017]
CPU: 53 UID: 0 PID: 970 Comm: systemd-udevd Not tainted 6.12.0-rc2+ #24
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009)
RIP: 0010:ts2020_probe+0xad/0xe10 [ts2020]
RSP: 0018:ffffc9000abbf598 EFLAGS: 00010202
RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffffffc0714809
RDX: 0000000000000002 RSI: ffff88811550be00 RDI: 0000000000000010
RBP: ffff888109868800 R08: 0000000000000001 R09: fffff52001577eb6
R10: 0000000000000000 R11: ffffc9000abbff50 R12: ffffffffc0714790
R13: 1ffff92001577eb8 R14: ffffffffc07190d0 R15: 0000000000000001
FS: 00007f95f13b98c0(0000) GS:ffff888149280000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000555d2634b000 CR3: 0000000152236000 CR4: 00000000000006f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
<TASK>
ts2020_probe+0xad/0xe10 [ts2020]
i2c_device_probe+0x421/0xb40
really_probe+0x266/0x850
...The cause of the problem is that when using sysfs to dynamically register an i2c device, there is no platform data, but the probe process of ts2020 needs to use platform data, resulting in a null pointer being accessed.
Solve this problem by adding checks to platform data.
--- drivers/media/dvb-frontends/ts2020.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/media/dvb-frontends/ts2020.c +7 -1
@@ -553,13 +553,19 @@ static void ts2020_regmap_unlock(void *_static int ts2020_probe (struct i2c_client *client) {struct ts2020_config *pdata = client->dev.platform_data; -struct dvb_frontend *fe = pdata->fe; +struct dvb_frontend *fe;struct ts2020_priv *dev;int ret;u8 u8tmp;unsigned int utmp;char *chip_str; +if (!pdata) { +dev_err (&client->dev,"platform data is mandatory\n" ); +return -EINVAL ; + } + + fe = pdata->fe; dev =kzalloc (sizeof (*dev),GFP_KERNEL );if (!dev) { ret = -ENOMEM ;
Greg Kroah-Hartman
maintainerPATCH 618/676 media: platform: exynos4-is: Fix an OF node reference leak in fimc_md_is_isp_available
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joe Hattori <[email protected]>
commit 8964eb23408243ae0016d1f8473c76f64ff25d20 upstream.
In fimc_md_is_isp_available(), of_get_child_by_name() is called to check if FIMC-IS is available. Current code does not decrement the refcount of the returned device node, which causes an OF node reference leak. Fix it by calling of_node_put() at the end of the variable scope.
--- drivers/media/platform/samsung/exynos4-is/media-dev.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/media/platform/samsung/exynos4-is/media-dev.h +3 -2
@@ -178,8 +178,9 @@ int fimc_md_set_camclk(struct v4l2_subde#ifdef CONFIG_OF static inline bool fimc_md_is_isp_available (struct device_node *node) { - node =of_get_child_by_name (node,FIMC_IS_OF_NODE_NAME ); -return node ?of_device_is_available (node) : false; + struct device_node *child __free(device_node) = +of_get_child_by_name (node,FIMC_IS_OF_NODE_NAME ); +return child ?of_device_is_available (child) : false; }#else #define fimc_md_is_isp_available (node) (false)
Greg Kroah-Hartman
maintainerPATCH 619/676 efi/libstub: Free correct pointer on failure
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ard Biesheuvel <[email protected]>
commit 06d39d79cbd5a91a33707951ebf2512d0e759847 upstream.
cmdline_ptr is an out parameter, which is not allocated by the function itself, and likely points into the caller's stack.
cmdline refers to the pool allocation that should be freed when cleaning up after a failure, so pass this instead to free_pool().
--- drivers/firmware/efi/libstub/efi-stub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/firmware/efi/libstub/efi-stub.c +1 -1
@@ -149,7 +149,7 @@ efi_status_t efi_handle_cmdline(efi_loadreturn EFI_SUCCESS ; fail_free_cmdline: -efi_bs_call (free_pool, cmdline_ptr); +efi_bs_call (free_pool, cmdline);return status; }
Greg Kroah-Hartman
maintainerPATCH 620/676 media: amphion: Fix pm_runtime_set_suspended() with runtime pm enabled
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
commit 316e74500d1c6589cba28cebe2864a0bceeb2396 upstream.
It is not valid to call pm_runtime_set_suspended() for devices with runtime PM enabled because it returns -EAGAIN if it is enabled already and working. So, call pm_runtime_disable() before to fix it.
--- drivers/media/platform/amphion/vpu_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/platform/amphion/vpu_drv.c +1 -1
@@ -151,8 +151,8 @@ err_add_decoder:media_device_cleanup (&vpu->mdev);v4l2_device_unregister (&vpu->v4l2_dev); err_vpu_deinit: -pm_runtime_set_suspended (dev);pm_runtime_disable (dev); +pm_runtime_set_suspended (dev);return ret; }
Greg Kroah-Hartman
maintainerPATCH 621/676 media: venus: Fix pm_runtime_set_suspended() with runtime pm enabled
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
commit 2a20869f7d798aa2b69e45b863eaf1b1ecf98278 upstream.
It is not valid to call pm_runtime_set_suspended() for devices with runtime PM enabled because it returns -EAGAIN if it is enabled already and working. So, call pm_runtime_disable() before to fix it.
--- drivers/media/platform/qcom/venus/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/platform/qcom/venus/core.c +1 -1
@@ -406,8 +406,8 @@ err_of_depopulate:of_platform_depopulate (dev); err_runtime_disable:pm_runtime_put_noidle (dev); -pm_runtime_set_suspended (dev);pm_runtime_disable (dev); +pm_runtime_set_suspended (dev);hfi_destroy (core); err_core_deinit:hfi_core_deinit (core, false);
Greg Kroah-Hartman
maintainerPATCH 622/676 media: gspca: ov534-ov772x: Fix off-by-one error in set_frame_rate()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
commit d2842dec577900031826dc44e9bf0c66416d7173 upstream.
In set_frame_rate(), select a rate in rate_0 or rate_1 by checking sd->frame_rate >= r->fps in a loop, but the loop condition terminates when the index reaches zero, which fails to check the last elememt in rate_0 or rate_1.
Check for >= 0 so that the last one in rate_0 or rate_1 is also checked.
--- drivers/media/usb/gspca/ov534.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/usb/gspca/ov534.c +1 -1
@@ -847,7 +847,7 @@ static void set_frame_rate(struct gspca_ r = rate_1; i =ARRAY_SIZE (rate_1); } -while (--i >0 ) { +while (--i >=0 ) {if (sd->frame_rate >= r->fps)break ; r++;
Greg Kroah-Hartman
maintainerPATCH 623/676 media: platform: allegro-dvt: Fix possible memory leak in allocate_buffers_internal()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gaosheng Cui <[email protected]>
commit 0f514068fbc5d4d189c817adc7c4e32cffdc2e47 upstream.
The buffer in the loop should be released under the exception path, otherwise there may be a memory leak here.
To mitigate this, free the buffer when allegro_alloc_buffer fails.
--- drivers/media/platform/allegro-dvt/allegro-core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/media/platform/allegro-dvt/allegro-core.c +3 -1
@@ -1509,8 +1509,10 @@ static int allocate_buffers_internal(strINIT_LIST_HEAD (&buffer->head); err =allegro_alloc_buffer (dev, buffer, size); -if (err) +if (err) { +kfree (buffer); goto err; + }list_add (&buffer->head, list); }
Greg Kroah-Hartman
maintainerPATCH 624/676 media: uvcvideo: Stop stream during unregister
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ricardo Ribalda <[email protected]>
commit c9ec6f1736363b2b2bb4e266997389740f628441 upstream.
uvc_unregister_video() can be called asynchronously from uvc_disconnect(). If the device is still streaming when that happens, a plethora of race conditions can occur.
Make sure that the device has stopped streaming before exiting this function.
If the user still holds handles to the driver's file descriptors, any ioctl will return -ENODEV from the v4l2 core.
This change makes uvc more consistent with the rest of the v4l2 drivers using the vb2_fop_* and vb2_ioctl_* helpers.
This driver (and many other usb drivers) always had this problem, but it wasn't possible to easily fix this until the vb2_video_unregister_device() helper was added. So the Fixes tag points to the creation of that helper.
--- drivers/media/usb/uvc/uvc_driver.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-)
drivers/media/usb/uvc/uvc_driver.c +31 -1
@@ -1919,11 +1919,41 @@ static void uvc_unregister_video(structstruct uvc_streaming *stream;list_for_each_entry (stream, &dev->streams, list) { +/* Nothing to do here, continue. */ if (!video_is_registered (&stream->vdev))continue ; +/* +* For stream->vdev we follow the same logic as: +* vb2_video_unregister_device(). +*/ + +/* 1. Take a reference to vdev */ +get_device (&stream->vdev.dev); + +/* 2. Ensure that no new ioctls can be called. */ video_unregister_device (&stream->vdev); -video_unregister_device (&stream->meta.vdev); + +/* 3. Wait for old ioctls to finish. */ +mutex_lock (&stream->mutex); + +/* 4. Stop streaming. */ +uvc_queue_release (&stream->queue); + +mutex_unlock (&stream->mutex); + +put_device (&stream->vdev.dev); + +/* +* For stream->meta.vdev we can directly call: +* vb2_video_unregister_device(). +*/ +vb2_video_unregister_device (&stream->meta.vdev); + +/* +* Now both vdevs are not streaming and all the ioctls will +* return -ENODEV. +*/ uvc_debugfs_cleanup_stream (stream); }
Greg Kroah-Hartman
maintainerPATCH 625/676 media: uvcvideo: Require entities to have a non-zero unique ID
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thadeu Lima de Souza Cascardo <[email protected]>
commit 3dd075fe8ebbc6fcbf998f81a75b8c4b159a6195 upstream.
Per UVC 1.1+ specification 3.7.2, units and terminals must have a non-zero unique ID.
``` Each Unit and Terminal within the video function is assigned a unique identification number, the Unit ID (UID) or Terminal ID (TID), contained in the bUnitID or bTerminalID field of the descriptor. The value 0x00 is reserved for undefined ID, ```
So, deny allocating an entity with ID 0 or an ID that belongs to a unit that is already added to the list of entities.
This also prevents some syzkaller reproducers from triggering warnings due to a chain of entities referring to themselves. In one particular case, an Output Unit is connected to an Input Unit, both with the same ID of 1. But when looking up for the source ID of the Output Unit, that same entity is found instead of the input entity, which leads to such warnings.
In another case, a backward chain was considered finished as the source ID was 0. Later on, that entity was found, but its pads were not valid.
Here is a sample stack trace for one of those cases.
[ 20.650953] usb 1-1: new high-speed USB device number 2 using dummy_hcd [ 20.830206] usb 1-1: Using ep0 maxpacket: 8 [ 20.833501] usb 1-1: config 0 descriptor?? [ 21.038518] usb 1-1: string descriptor 0 read error: -71 [ 21.038893] usb 1-1: Found UVC 0.00 device <unnamed> (2833:0201) [ 21.039299] uvcvideo 1-1:0.0: Entity type for entity Output 1 was not initialized! [ 21.041583] uvcvideo 1-1:0.0: Entity type for entity Input 1 was not initialized! [ 21.042218] ------------[ cut here ]------------ [ 21.042536] WARNING: CPU: 0 PID: 9 at drivers/media/mc/mc-entity.c:1147 media_create_pad_link+0x2c4/0x2e0 [ 21.043195] Modules linked in: [ 21.043535] CPU: 0 UID: 0 PID: 9 Comm: kworker/0:1 Not tainted 6.11.0-rc7-00030-g3480e43aeccf #444 [ 21.044101] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.15.0-1 04/01/2014 [ 21.044639] Workqueue: usb_hub_wq hub_event [ 21.045100] RIP: 0010:media_create_pad_link+0x2c4/0x2e0 [ 21.045508] Code: fe e8 20 01 00 00 b8 f4 ff ff ff 48 83 c4 30 5b 41 5c 41 5d 41 5e 41 5f 5d c3 cc cc cc cc 0f 0b eb e9 0f 0b eb 0a 0f 0b eb 06 <0f> 0b eb 02 0f 0b b8 ea ff ff ff eb d4 66 2e 0f 1f 84 00 00 00 00 [ 21.046801] RSP: 0018:ffffc9000004b318 EFLAGS: 00010246 [ 21.047227] RAX: ffff888004e5d458 RBX: 0000000000000000 RCX: ffffffff818fccf1 [ 21.047719] RDX: 000000000000007b RSI: 0000000000000000 RDI: ffff888004313290 [ 21.048241] RBP: ffff888004313290 R08: 0001ffffffffffff R09: 0000000000000000 [ 21.048701] R10: 0000000000000013 R11: 0001888004313290 R12: 0000000000000003 [ 21.049138] R13: ffff888004313080 R14: ffff888004313080 R15: 0000000000000000 [ 21.049648] FS: 0000000000000000(0000) GS:ffff88803ec00000(0000) knlGS:0000000000000000 [ 21.050271] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 21.050688] CR2: 0000592cc27635b0 CR3: 000000000431c000 CR4: 0000000000750ef0 [ 21.051136] PKRU: 55555554 [ 21.051331] Call Trace: [ 21.051480] <TASK> [ 21.051611] ? __warn+0xc4/0x210 [ 21.051861] ? media_create_pad_link+0x2c4/0x2e0 [ 21.052252] ? report_bug+0x11b/0x1a0 [ 21.052540] ? trace_hardirqs_on+0x31/0x40 [ 21.052901] ? handle_bug+0x3d/0x70 [ 21.053197] ? exc_invalid_op+0x1a/0x50 [ 21.053511] ? asm_exc_invalid_op+0x1a/0x20 [ 21.053924] ? media_create_pad_link+0x91/0x2e0 [ 21.054364] ? media_create_pad_link+0x2c4/0x2e0 [ 21.054834] ? media_create_pad_link+0x91/0x2e0 [ 21.055131] ? _raw_spin_unlock+0x1e/0x40 [ 21.055441] ? __v4l2_device_register_subdev+0x202/0x210 [ 21.055837] uvc_mc_register_entities+0x358/0x400 [ 21.056144] uvc_register_chains+0x1fd/0x290 [ 21.056413] uvc_probe+0x380e/0x3dc0 [ 21.056676] ? __lock_acquire+0x5aa/0x26e0 [ 21.056946] ? find_held_lock+0x33/0xa0 [ 21.057196] ? kernfs_activate+0x70/0x80 [ 21.057533] ? usb_match_dynamic_id+0x1b/0x70 [ 21.057811] ? find_held_lock+0x33/0xa0 [ 21.058047] ? usb_match_dynamic_id+0x55/0x70 [ 21.058330] ? lock_release+0x124/0x260 [ 21.058657] ? usb_match_one_id_intf+0xa2/0x100 [ 21.058997] usb_probe_interface+0x1ba/0x330 [ 21.059399] really_probe+0x1ba/0x4c0 [ 21.059662] __driver_probe_device+0xb2/0x180 [ 21.059944] driver_probe_device+0x5a/0x100 [ 21.060170] __device_attach_driver+0xe9/0x160 [ 21.060427] ? __pfx___device_attach_driver+0x10/0x10 [ 21.060872] bus_for_each_drv+0xa9/0x100 [ 21.061312] __device_attach+0xed/0x190 [ 21.061812] device_initial_probe+0xe/0x20 [ 21.062229] bus_probe_device+0x4d/0xd0 [ 21.062590] device_add+0x308/0x590 [ 21.062912] usb_set_configuration+0x7b6/0xaf0 [ 21.063403] usb_generic_driver_probe+0x36/0x80 [ 21.063714] usb_probe_device+0x7b/0x130 [ 21.063936] really_probe+0x1ba/0x4c0 [ 21.064111] __driver_probe_device+0xb2/0x180 [ 21.064577] driver_probe_device+0x5a/0x100 [ 21.065019] __device_attach_driver+0xe9/0x160 [ 21.065403] ? __pfx___device_attach_driver+0x10/0x10 [ 21.065820] bus_for_each_drv+0xa9/0x100 [ 21.066094] __device_attach+0xed/0x190 [ 21.066535] device_initial_probe+0xe/0x20 [ 21.066992] bus_probe_device+0x4d/0xd0 [ 21.067250] device_add+0x308/0x590 [ 21.067501] usb_new_device+0x347/0x610 [ 21.067817] hub_event+0x156b/0x1e30 [ 21.068060] ? process_scheduled_works+0x48b/0xaf0 [ 21.068337] process_scheduled_works+0x5a3/0xaf0 [ 21.068668] worker_thread+0x3cf/0x560 [ 21.068932] ? kthread+0x109/0x1b0 [ 21.069133] kthread+0x197/0x1b0 [ 21.069343] ? __pfx_worker_thread+0x10/0x10 [ 21.069598] ? __pfx_kthread+0x10/0x10 [ 21.069908] ret_from_fork+0x32/0x40 [ 21.070169] ? __pfx_kthread+0x10/0x10 [ 21.070424] ret_from_fork_asm+0x1a/0x30 [ 21.070737] </TASK>
--- drivers/media/usb/uvc/uvc_driver.c | 70 ++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 27 deletions(-)
drivers/media/usb/uvc/uvc_driver.c +43 -27
@@ -775,14 +775,27 @@ static const u8 uvc_media_transport_inpuUVC_GUID_UVC_MEDIA_TRANSPORT_INPUT ;static const u8 uvc_processing_guid[16 ] =UVC_GUID_UVC_PROCESSING ; -static struct uvc_entity *uvc_alloc_entity (u16 type,u16 id, -unsigned int num_pads,unsigned int extra_size) +static struct uvc_entity *uvc_alloc_new_entity (struct uvc_device *dev,u16 type, +u16 id,unsigned int num_pads, +unsigned int extra_size) {struct uvc_entity *entity;unsigned int num_inputs;unsigned int size;unsigned int i; +/* Per UVC 1.1+ spec 3.7.2, the ID should be non-zero. */ +if (id ==0 ) { +dev_err (&dev->udev->dev,"Found Unit with invalid ID 0.\n" ); +return ERR_PTR (-EINVAL ); + } + +/* Per UVC 1.1+ spec 3.7.2, the ID is unique. */ +if (uvc_entity_by_id (dev, id)) { +dev_err (&dev->udev->dev,"Found multiple Units with ID %u\n" , id); +return ERR_PTR (-EINVAL ); + } + extra_size =roundup (extra_size,sizeof (*entity->pads));if (num_pads) num_inputs = type &UVC_TERM_OUTPUT ? num_pads : num_pads -1 ;
@@ -792,7 +805,7 @@ static struct uvc_entity *uvc_alloc_enti + num_inputs; entity =kzalloc (size,GFP_KERNEL );if (entity ==NULL ) -return NULL ; +return ERR_PTR (-ENOMEM ); entity->id = id; entity->type = type;
@@ -904,10 +917,10 @@ static int uvc_parse_vendor_control(strubreak ; } - unit =uvc_alloc_entity (UVC_VC_EXTENSION_UNIT , buffer[3 ], - p +1 ,2 *n); -if (unit ==NULL ) -return -ENOMEM ; + unit =uvc_alloc_new_entity (dev,UVC_VC_EXTENSION_UNIT , + buffer[3 ], p +1 ,2 * n); +if (IS_ERR (unit)) +return PTR_ERR (unit);memcpy (unit->guid, &buffer[4 ],16 ); unit->extension.bNumControls = buffer[20 ];
@@ -1016,10 +1029,10 @@ static int uvc_parse_standard_control(streturn -EINVAL ; } - term =uvc_alloc_entity (type |UVC_TERM_INPUT , buffer[3 ], -1 , n + p); -if (term ==NULL ) -return -ENOMEM ; + term =uvc_alloc_new_entity (dev, type |UVC_TERM_INPUT , + buffer[3 ],1 , n + p); +if (IS_ERR (term)) +return PTR_ERR (term);if (UVC_ENTITY_TYPE (term) ==UVC_ITT_CAMERA ) { term->camera.bControlSize = n;
@@ -1075,10 +1088,10 @@ static int uvc_parse_standard_control(streturn 0 ; } - term =uvc_alloc_entity (type |UVC_TERM_OUTPUT , buffer[3 ], -1 ,0 ); -if (term ==NULL ) -return -ENOMEM ; + term =uvc_alloc_new_entity (dev, type |UVC_TERM_OUTPUT , + buffer[3 ],1 ,0 ); +if (IS_ERR (term)) +return PTR_ERR (term);memcpy (term->baSourceID, &buffer[7 ],1 );
@@ -1097,9 +1110,10 @@ static int uvc_parse_standard_control(streturn -EINVAL ; } - unit =uvc_alloc_entity (buffer[2 ], buffer[3 ], p +1 ,0 ); -if (unit ==NULL ) -return -ENOMEM ; + unit =uvc_alloc_new_entity (dev, buffer[2 ], buffer[3 ], + p +1 ,0 ); +if (IS_ERR (unit)) +return PTR_ERR (unit);memcpy (unit->baSourceID, &buffer[5 ], p);
@@ -1119,9 +1133,9 @@ static int uvc_parse_standard_control(streturn -EINVAL ; } - unit =uvc_alloc_entity (buffer[2 ], buffer[3 ],2 , n); -if (unit ==NULL ) -return -ENOMEM ; + unit =uvc_alloc_new_entity (dev, buffer[2 ], buffer[3 ],2 , n); +if (IS_ERR (unit)) +return PTR_ERR (unit);memcpy (unit->baSourceID, &buffer[4 ],1 ); unit->processing.wMaxMultiplier =
@@ -1148,9 +1162,10 @@ static int uvc_parse_standard_control(streturn -EINVAL ; } - unit =uvc_alloc_entity (buffer[2 ], buffer[3 ], p +1 , n); -if (unit ==NULL ) -return -ENOMEM ; + unit =uvc_alloc_new_entity (dev, buffer[2 ], buffer[3 ], + p +1 , n); +if (IS_ERR (unit)) +return PTR_ERR (unit);memcpy (unit->guid, &buffer[4 ],16 ); unit->extension.bNumControls = buffer[20 ];
@@ -1290,9 +1305,10 @@ static int uvc_gpio_parse(struct uvc_devreturn dev_err_probe (&dev->udev->dev, irq,"No IRQ for privacy GPIO\n" ); - unit =uvc_alloc_entity (UVC_EXT_GPIO_UNIT ,UVC_EXT_GPIO_UNIT_ID ,0 ,1 ); -if (!unit) -return -ENOMEM ; + unit =uvc_alloc_new_entity (dev,UVC_EXT_GPIO_UNIT , +UVC_EXT_GPIO_UNIT_ID ,0 ,1 ); +if (IS_ERR (unit)) +return PTR_ERR (unit); unit->gpio.gpio_privacy = gpio_privacy; unit->gpio.irq = irq;
Greg Kroah-Hartman
maintainerPATCH 626/676 ovl: Filter invalid inodes with missing lookup function
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vasiliy Kovalev <[email protected]>
commit c8b359dddb418c60df1a69beea01d1b3322bfe83 upstream.
Add a check to the ovl_dentry_weird() function to prevent the processing of directory inodes that lack the lookup function. This is important because such inodes can cause errors in overlayfs when passed to the lowerstack.
--- fs/overlayfs/util.c | 3 +++ 1 file changed, 3 insertions(+)
fs/overlayfs/util.c +3 -0
@@ -171,6 +171,9 @@ void ovl_dentry_init_flags(struct dentrybool ovl_dentry_weird (struct dentry *dentry) { +if (!d_can_lookup (dentry) && !d_is_file (dentry) && !d_is_symlink (dentry)) +return true; + return dentry->d_flags & (DCACHE_NEED_AUTOMOUNT | DCACHE_MANAGE_TRANSIT | DCACHE_OP_HASH |
Greg Kroah-Hartman
maintainerPATCH 627/676 maple_tree: refine mas_store_root() on storing NULL
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wei Yang <[email protected]>
commit 0ea120b278ad7f7cfeeb606e150ad04b192df60b upstream.
Currently, when storing NULL on mas_store_root(), the behavior could be improved.
Storing NULLs over the entire tree may result in a node being used to store a single range. Further stores of NULL may cause the node and tree to be corrupt and cause incorrect behaviour. Fixing the store to the root null fixes the issue by ensuring that a range of 0 - ULONG_MAX results in an empty tree.
Users of the tree may experience incorrect values returned if the tree was expanded to store values, then overwritten by all NULLS, then continued to store NULLs over the empty area.
For example possible cases are:
* store NULL at any range result a new node
* store NULL at range [m, n] where m > 0 to a single entry tree result a new node with range [m, n] set to NULL
* store NULL at range [m, n] where m > 0 to an empty tree result consecutive NULL slot
* it allows for multiple NULL entries by expanding root
to store NULLs to an empty tree
This patch tries to improve in:
* memory efficient by setting to empty tree instead of using a node
* remove the possibility of consecutive NULL slot which will prohibit extended null in later operation
--- lib/maple_tree.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
lib/maple_tree.c +12 -1
@@ -3547,9 +3547,20 @@ static inline int mas_root_expand(structreturn slot; } +/* +* mas_store_root() - Storing value into root. +* @mas: The maple state +* @entry: The entry to store. +* +* There is no root node now and we are storing a value into the root - this +* function either assigns the pointer or expands into a node. +*/ static inline void mas_store_root (struct ma_state *mas,void *entry) { -if (likely ((mas->last !=0 ) || (mas->index !=0 ))) +if (!entry) { +if (!mas->index) +rcu_assign_pointer (mas->tree->ma_root,NULL ); + }else if (likely ((mas->last !=0 ) || (mas->index !=0 )))mas_root_expand (mas, entry);else if (((unsigned long ) (entry) &3 ) ==2 )mas_root_expand (mas, entry);
Greg Kroah-Hartman
maintainerPATCH 628/676 ftrace: Fix regression with module command in stack_trace_filter
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: guoweikang <[email protected]>
commit 45af52e7d3b8560f21d139b3759735eead8b1653 upstream.
When executing the following command:
# echo "write*:mod:ext3" > /sys/kernel/tracing/stack_trace_filter
The current mod command causes a null pointer dereference. While commit 0f17976568b3f ("ftrace: Fix regression with module command in stack_trace_filter") has addressed part of the issue, it left a corner case unhandled, which still results in a kernel crash.
--- kernel/trace/ftrace.c | 3 +++ 1 file changed, 3 insertions(+)
kernel/trace/ftrace.c +3 -0
@@ -4562,6 +4562,9 @@ ftrace_mod_callback(struct trace_array *char *func;int ret; +if (!tr) +return -ENODEV ; +/* match_records() modifies func, and we need the original */ func =kstrdup (func_orig,GFP_KERNEL );if (!func)
Greg Kroah-Hartman
maintainerPATCH 629/676 vmstat: call fold_vm_zone_numa_events() before show per zone NUMA event
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: MengEn Sun <[email protected]>
commit 2ea80b039b9af0b71c00378523b71c254fb99c23 upstream.
Since 5.14-rc1, NUMA events will only be folded from per-CPU statistics to per zone and global statistics when the user actually needs it.
Currently, the kernel has performs the fold operation when reading /proc/vmstat, but does not perform the fold operation in /proc/zoneinfo. This can lead to inaccuracies in the following statistics in zoneinfo:
- numa_hit
- numa_miss
- numa_foreign
- numa_interleave
- numa_local
- numa_other
Therefore, before printing per-zone vm_numa_event when reading /proc/zoneinfo, we should also perform the fold operation.
--- mm/vmstat.c | 1 + 1 file changed, 1 insertion(+)
mm/vmstat.c +1 -0
@@ -1723,6 +1723,7 @@ static void zoneinfo_show_print(struct s zone_page_state(zone, i));#ifdef CONFIG_NUMA +fold_vm_zone_numa_events (zone);for (i =0 ; i <NR_VM_NUMA_EVENT_ITEMS ; i++)seq_printf (m,"\n %-12s %lu" ,numa_stat_name (i),zone_numa_event_state (zone, i));
Greg Kroah-Hartman
maintainerPATCH 630/676 zram: clear IDLE flag after recompression
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sergey Senozhatsky <[email protected]>
commit f85219096648b251a81e9fe24a1974590cfc417d upstream.
Patch series "zram: IDLE flag handling fixes", v2.
zram can wrongly preserve ZRAM_IDLE flag on its entries which can result in premature post-processing (writeback and recompression) of such entries.
This patch (of 2)
Recompression should clear ZRAM_IDLE flag on the entries it has accessed, because otherwise some entries, specifically those for which recompression has failed, become immediate candidate entries for another post-processing (e.g. writeback).
Consider the following case:
- recompression marks entries IDLE every 4 hours and attempts to recompress them
- some entries are incompressible, so we keep them intact and hence preserve IDLE flag
- writeback marks entries IDLE every 8 hours and writebacks IDLE entries, however we have IDLE entries left from recompression, so writeback prematurely writebacks those entries.
The bug was reported by Shin Kawamura.
--- drivers/block/zram/zram_drv.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/block/zram/zram_drv.c +7 -0
@@ -1600,6 +1600,13 @@ static int zram_recompress(struct zram *if (ret)return ret; +/* +* We touched this entry so mark it as non-IDLE. This makes sure that +* we don't preserve IDLE flag and don't incorrectly pick this entry +* for different post-processing type (e.g. writeback). +*/ +zram_clear_flag (zram, index,ZRAM_IDLE ); + class_index_old =zs_lookup_class_index (zram->mem_pool, comp_len_old);/* * Iterate the secondary comp algorithms list (in order of priority)
Greg Kroah-Hartman
maintainerPATCH 631/676 iommu/io-pgtable-arm: Fix stage-2 map/unmap for concatenated tables
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mostafa Saleh <[email protected]>
commit d71fa842d33c48ac2809ae11d2379b5a788792cb upstream.
ARM_LPAE_LVL_IDX() takes into account concatenated PGDs and can return an index spanning multiple page-table pages given a sufficiently large input address. However, when the resulting index is used to calculate the number of remaining entries in the page, the possibility of concatenation is ignored and we end up computing a negative upper bound:
max_entries = ARM_LPAE_PTES_PER_TABLE(data) - map_idx_start;
On the map path, this results in a negative 'mapped' value being returned but on the unmap path we can leak child tables if they are skipped in __arm_lpae_free_pgtable().
Introduce an arm_lpae_max_entries() helper to convert a table index into the remaining number of entries within a single page-table page.
--- drivers/iommu/io-pgtable-arm.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
drivers/iommu/io-pgtable-arm.c +15 -3
@@ -180,6 +180,18 @@ static phys_addr_t iopte_to_paddr(arm_lpreturn (paddr | (paddr << (48 -12 ))) & (ARM_LPAE_PTE_ADDR_MASK <<4 ); } +/* +* Convert an index returned by ARM_LPAE_PGD_IDX(), which can point into +* a concatenated PGD, into the maximum number of entries that can be +* mapped in the same table page. +*/ +static inline int arm_lpae_max_entries (int i,struct arm_lpae_io_pgtable *data) +{ +int ptes_per_table =ARM_LPAE_PTES_PER_TABLE (data); + +return ptes_per_table - (i & (ptes_per_table -1 )); +} +static bool selftest_running = false;static dma_addr_t __arm_lpae_dma_addr (void *pages)
@@ -357,7 +369,7 @@ static int __arm_lpae_map(struct arm_lpa/* If we can install a leaf entry at this level, then do so */ if (size == block_size) { - max_entries =ARM_LPAE_PTES_PER_TABLE (data) - map_idx_start; + max_entries =arm_lpae_max_entries (map_idx_start, data); num_entries =min_t (int, pgcount, max_entries); ret =arm_lpae_init_pte (data, iova, paddr, prot, lvl, num_entries, ptep);if (!ret)
@@ -557,7 +569,7 @@ static size_t arm_lpae_split_blk_unmap(sif (size == split_sz) { unmap_idx_start =ARM_LPAE_LVL_IDX (iova, lvl, data); - max_entries = ptes_per_table - unmap_idx_start; + max_entries =arm_lpae_max_entries (unmap_idx_start, data); num_entries =min_t (int, pgcount, max_entries); }
@@ -615,7 +627,7 @@ static size_t __arm_lpae_unmap(struct ar/* If the size matches this level, we're in the right place */ if (size ==ARM_LPAE_BLOCK_SIZE (lvl, data)) { - max_entries =ARM_LPAE_PTES_PER_TABLE (data) - unmap_idx_start; + max_entries =arm_lpae_max_entries (unmap_idx_start, data); num_entries =min_t (int, pgcount, max_entries);while (i < num_entries) {
Greg Kroah-Hartman
maintainerPATCH 632/676 leds: lp55xx: Remove redundant test for invalid channel number
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Vokáč <[email protected]>
commit 09b1ef9813a0742674f7efe26104403ca94a1b4a upstream.
Since commit 92a81562e695 ("leds: lp55xx: Add multicolor framework support to lp55xx") there are two subsequent tests if the chan_nr (reg property) is in valid range. One in the lp55xx_init_led() function and one in the lp55xx_parse_common_child() function that was added with the mentioned commit.
There are two issues with that.
First is in the lp55xx_parse_common_child() function where the reg property is tested right after it is read from the device tree. Test for the upper range is not correct though. Valid reg values are 0 to (max_channel - 1) so it should be >=.
Second issue is that in case the parsed value is out of the range the probe just fails and no error message is shown as the code never reaches the second test that prints and error message.
Remove the test form lp55xx_parse_common_child() function completely and keep the one in lp55xx_init_led() function to deal with it.
--- drivers/leds/leds-lp55xx-common.c | 3 --- 1 file changed, 3 deletions(-)
drivers/leds/leds-lp55xx-common.c +0 -3
@@ -580,9 +580,6 @@ static int lp55xx_parse_common_child(strif (ret)return ret; -if (*chan_nr <0 || *chan_nr > cfg->max_channel) -return -EINVAL ; -return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 633/676 clk: qcom: gcc-qcs404: fix initial rate of GPLL3
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gabor Juhos <[email protected]>
commit 36d202241d234fa4ac50743510d098ad52bd193a upstream.
The comment before the config of the GPLL3 PLL says that the PLL should run at 930 MHz. In contrary to this, calculating the frequency from the current configuration values by using 19.2 MHz as input frequency defined in 'qcs404.dtsi', it gives 921.6 MHz:
$ xo=19200000; l=48; alpha=0x0; alpha_hi=0x0 $ echo "$xo * ($((l)) + $(((alpha_hi << 32 | alpha) >> 8)) / 2^32)" | bc -l 921600000.00000000000000000000
Set 'alpha_hi' in the configuration to a value used in downstream kernels [1][2] in order to get the correct output rate:
$ xo=19200000; l=48; alpha=0x0; alpha_hi=0x70 $ echo "$xo * ($((l)) + $(((alpha_hi << 32 | alpha) >> 8)) / 2^32)" | bc -l 930000000.00000000000000000000
The change is based on static code analysis, compile tested only.
[1] https://git.codelinaro.org/clo/la/kernel/msm-5.4/-/blob/kernel.lnx.5.4.r56-rel/drivers/clk/qcom/gcc-qcs404.c?ref_type=heads#L335
[2} https://git.codelinaro.org/clo/la/kernel/msm-5.15/-/blob/kernel.lnx.5.15.r49-rel/drivers/clk/qcom/gcc-qcs404.c?ref_type=heads#L127
--- drivers/clk/qcom/gcc-qcs404.c | 1 + 1 file changed, 1 insertion(+)
drivers/clk/qcom/gcc-qcs404.c +1 -0
@@ -131,6 +131,7 @@ static struct clk_alpha_pll gpll1_out_ma/* 930MHz configuration */ static const struct alpha_pll_config gpll3_config = { .l =48 , + .alpha_hi =0x70 , .alpha =0x0 , .alpha_en_mask =BIT (24 ), .post_div_mask =0xf <<8 ,
Greg Kroah-Hartman
maintainerPATCH 634/676 ad7780: fix division by zero in ad7780_write_raw()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zicheng Qu <[email protected]>
commit c174b53e95adf2eece2afc56cd9798374919f99a upstream.
In the ad7780_write_raw() , val2 can be zero, which might lead to a division by zero error in DIV_ROUND_CLOSEST(). The ad7780_write_raw() is based on iio_info's write_raw. While val is explicitly declared that can be zero (in read mode), val2 is not specified to be non-zero.
--- drivers/iio/adc/ad7780.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/adc/ad7780.c +1 -1
@@ -152,7 +152,7 @@ static int ad7780_write_raw(struct iio_dswitch (m) {case IIO_CHAN_INFO_SCALE : -if (val !=0 ) +if (val !=0 || val2 ==0 )return -EINVAL ; vref = st->int_vref_mv *1000000LL ;
Greg Kroah-Hartman
maintainerPATCH 635/676 ARM: 9429/1: ioremap: Sync PGDs for VMALLOC shadow
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <[email protected]>
commit d6e6a74d4cea853b5321eeabb69c611148eedefe upstream.
When sync:ing the VMALLOC area to other CPUs, make sure to also sync the KASAN shadow memory for the VMALLOC area, so that we don't get stale entries for the shadow memory in the top level PGD.
Since we are now copying PGDs in two instances, create a helper function named memcpy_pgd() to do the actual copying, and create a helper to map the addresses of VMALLOC_START and VMALLOC_END into the corresponding shadow memory.
--- arch/arm/mm/ioremap.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-)
arch/arm/mm/ioremap.c +29 -4
@@ -23,6 +23,7 @@*/ #include <linux/module.h> #include <linux/errno.h> +#include <linux/kasan.h> #include <linux/mm.h> #include <linux/vmalloc.h> #include <linux/io.h>
@@ -115,16 +116,40 @@ int ioremap_page(unsigned long virt, uns }EXPORT_SYMBOL (ioremap_page); +#ifdef CONFIG_KASAN +static unsigned long arm_kasan_mem_to_shadow (unsigned long addr) +{ +return (unsigned long )kasan_mem_to_shadow ((void *)addr); +} +#else +static unsigned long arm_kasan_mem_to_shadow (unsigned long addr) +{ +return 0 ; +} +#endif + +static void memcpy_pgd (struct mm_struct *mm,unsigned long start, +unsigned long end) +{ + end =ALIGN (end,PGDIR_SIZE ); +memcpy (pgd_offset (mm, start),pgd_offset_k (start), +sizeof (pgd_t) * (pgd_index (end) -pgd_index (start))); +} +void __check_vmalloc_seq (struct mm_struct *mm) {int seq; do { seq = atomic_read(&init_mm.context.vmalloc_seq); - memcpy(pgd_offset(mm, VMALLOC_START), - pgd_offset_k(VMALLOC_START), - sizeof(pgd_t) * (pgd_index(VMALLOC_END) - - pgd_index(VMALLOC_START))); + memcpy_pgd(mm, VMALLOC_START, VMALLOC_END); + if (IS_ENABLED(CONFIG_KASAN_VMALLOC)) { + unsigned long start = + arm_kasan_mem_to_shadow(VMALLOC_START); + unsigned long end = + arm_kasan_mem_to_shadow(VMALLOC_END); + memcpy_pgd(mm, start, end); + } /* * Use a store-release so that other CPUs that observe the * counter's new value are guaranteed to see the results of the
Greg Kroah-Hartman
maintainerPATCH 636/676 s390/entry: Mark IRQ entries to fix stack depot warnings
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vasily Gorbik <[email protected]>
commit 45c9f2b856a075a34873d00788d2e8a250c1effd upstream.
The stack depot filters out everything outside of the top interrupt context as an uninteresting or irrelevant part of the stack traces. This helps with stack trace de-duplication, avoiding an explosion of saved stack traces that share the same IRQ context code path but originate from different randomly interrupted points, eventually exhausting the stack depot.
Filtering uses in_irqentry_text() to identify functions within the .irqentry.text and .softirqentry.text sections, which then become the last stack trace entries being saved.
While __do_softirq() is placed into the .softirqentry.text section by common code, populating .irqentry.text is architecture-specific.
Currently, the .irqentry.text section on s390 is empty, which prevents stack depot filtering and de-duplication and could result in warnings like:
Stack depot reached limit capacity
WARNING: CPU: 0 PID: 286113 at lib/stackdepot.c:252 depot_alloc_stack+0x39a/0x3c8
with PREEMPT and KASAN enabled.
Fix this by moving the IO/EXT interrupt handlers from .kprobes.text into the .irqentry.text section and updating the kprobes blacklist to include the .irqentry.text section.
This is done only for asynchronous interrupts and explicitly not for program checks, which are synchronous and where the context beyond the program check is important to preserve. Despite machine checks being somewhat in between, they are extremely rare, and preserving context when possible is also of value.
SVCs and Restart Interrupts are not relevant, one being always at the boundary to user space and the other being a one-time thing.
IRQ entries filtering is also optionally used in ftrace function graph, where the same logic applies.
--- arch/s390/kernel/entry.S | 4 ++++ arch/s390/kernel/kprobes.c | 6 ++++++ 2 files changed, 10 insertions(+)
arch/s390/kernel/entry.S +4 -0
@@ -458,9 +458,13 @@ SYM_CODE_START(\name) SYM_CODE_END(\name) .endm + .section .irqentry.text, "ax" + INT_HANDLER ext_int_handler,__LC_EXT_OLD_PSW,do_ext_irq INT_HANDLER io_int_handler,__LC_IO_OLD_PSW,do_io_irq + .section .kprobes.text, "ax" + /* * Load idle PSW. */
arch/s390/kernel/kprobes.c +6 -0
@@ -518,6 +518,12 @@ int __init arch_init_kprobes(void)return 0 ; } +int __init arch_populate_kprobe_blacklist (void ) +{ +return kprobe_add_area_blacklist ((unsigned long )__irqentry_text_start, + (unsigned long )__irqentry_text_end); +} +int arch_trampoline_kprobe (struct kprobe *p) {return 0 ;
Greg Kroah-Hartman
maintainerPATCH 637/676 ARM: 9430/1: entry: Do a dummy read from VMAP shadow
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <[email protected]>
commit 44e9a3bb76e5f2eecd374c8176b2c5163c8bb2e2 upstream.
When switching task, in addition to a dummy read from the new VMAP stack, also do a dummy read from the VMAP stack's corresponding KASAN shadow memory to sync things up in the new MM context.
--- arch/arm/kernel/entry-armv.S | 8 ++++++++ 1 file changed, 8 insertions(+)
arch/arm/kernel/entry-armv.S +8 -0
@@ -25,6 +25,7 @@ #include <asm/tls.h> #include <asm/system_info.h> #include <asm/uaccess-asm.h> +#include <asm/kasan_def.h> #include "entry-header.S" #include <asm/probes.h>
@@ -555,6 +556,13 @@ ENTRY(__switch_to) @ entries covering the vmalloc region. @ ldr r2, [ip] +#ifdef CONFIG_KASAN_VMALLOC + @ Also dummy read from the KASAN shadow memory for the new stack if we + @ are using KASAN + mov_l r2, KASAN_SHADOW_OFFSET + add r2, r2, ip, lsr #KASAN_SHADOW_SCALE_SHIFT + ldr r2, [r2] +#endif #endif @ When CONFIG_THREAD_INFO_IN_TASK=n, the update of SP itself is what
Greg Kroah-Hartman
maintainerPATCH 638/676 ARM: 9431/1: mm: Pair atomic_set_release() with _read_acquire()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <[email protected]>
commit 93ee385254d53849c01dd8ab9bc9d02790ee7f0e upstream.
The code for syncing vmalloc memory PGD pointers is using atomic_read() in pair with atomic_set_release() but the proper pairing is atomic_read_acquire() paired with atomic_set_release().
This is done to clearly instruct the compiler to not reorder the memcpy() or similar calls inside the section so that we do not observe changes to init_mm. memcpy() calls should be identified by the compiler as having unpredictable side effects, but let's try to be on the safe side.
--- arch/arm/mm/ioremap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mm/ioremap.c +1 -1
@@ -141,7 +141,7 @@ void __check_vmalloc_seq(struct mm_strucint seq; do { - seq = atomic_read(&init_mm.context.vmalloc_seq); + seq = atomic_read_acquire(&init_mm.context.vmalloc_seq); memcpy_pgd(mm, VMALLOC_START, VMALLOC_END); if (IS_ENABLED(CONFIG_KASAN_VMALLOC)) { unsigned long start =
Greg Kroah-Hartman
maintainerPATCH 639/676 mm/slub: Avoid list corruption when removing a slab from the full list
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: yuan.gao <[email protected]>
commit dbc16915279a548a204154368da23d402c141c81 upstream.
Boot with slub_debug=UFPZ.
If allocated object failed in alloc_consistency_checks, all objects of the slab will be marked as used, and then the slab will be removed from the partial list.
When an object belonging to the slab got freed later, the remove_full() function is called. Because the slab is neither on the partial list nor on the full list, it eventually lead to a list corruption (actually a list poison being detected).
So we need to mark and isolate the slab page with metadata corruption, do not put it back in circulation.
Because the debug caches avoid all the fastpaths, reusing the frozen bit to mark slab page with metadata corruption seems to be fine.
[ 4277.385669] list_del corruption, ffffea00044b3e50->next is LIST_POISON1 (dead000000000100) [ 4277.387023] ------------[ cut here ]------------ [ 4277.387880] kernel BUG at lib/list_debug.c:56! [ 4277.388680] invalid opcode: 0000 [#1] PREEMPT SMP PTI [ 4277.389562] CPU: 5 PID: 90 Comm: kworker/5:1 Kdump: loaded Tainted: G OE 6.6.1-1 #1 [ 4277.392113] Workqueue: xfs-inodegc/vda1 xfs_inodegc_worker [xfs] [ 4277.393551] RIP: 0010:__list_del_entry_valid_or_report+0x7b/0xc0 [ 4277.394518] Code: 48 91 82 e8 37 f9 9a ff 0f 0b 48 89 fe 48 c7 c7 28 49 91 82 e8 26 f9 9a ff 0f 0b 48 89 fe 48 c7 c7 58 49 91 [ 4277.397292] RSP: 0018:ffffc90000333b38 EFLAGS: 00010082 [ 4277.398202] RAX: 000000000000004e RBX: ffffea00044b3e50 RCX: 0000000000000000 [ 4277.399340] RDX: 0000000000000002 RSI: ffffffff828f8715 RDI: 00000000ffffffff [ 4277.400545] RBP: ffffea00044b3e40 R08: 0000000000000000 R09: ffffc900003339f0 [ 4277.401710] R10: 0000000000000003 R11: ffffffff82d44088 R12: ffff888112cf9910 [ 4277.402887] R13: 0000000000000001 R14: 0000000000000001 R15: ffff8881000424c0 [ 4277.404049] FS: 0000000000000000(0000) GS:ffff88842fd40000(0000) knlGS:0000000000000000 [ 4277.405357] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 4277.406389] CR2: 00007f2ad0b24000 CR3: 0000000102a3a006 CR4: 00000000007706e0 [ 4277.407589] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 4277.408780] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 4277.410000] PKRU: 55555554 [ 4277.410645] Call Trace: [ 4277.411234] <TASK> [ 4277.411777] ? die+0x32/0x80 [ 4277.412439] ? do_trap+0xd6/0x100 [ 4277.413150] ? __list_del_entry_valid_or_report+0x7b/0xc0 [ 4277.414158] ? do_error_trap+0x6a/0x90 [ 4277.414948] ? __list_del_entry_valid_or_report+0x7b/0xc0 [ 4277.415915] ? exc_invalid_op+0x4c/0x60 [ 4277.416710] ? __list_del_entry_valid_or_report+0x7b/0xc0 [ 4277.417675] ? asm_exc_invalid_op+0x16/0x20 [ 4277.418482] ? __list_del_entry_valid_or_report+0x7b/0xc0 [ 4277.419466] ? __list_del_entry_valid_or_report+0x7b/0xc0 [ 4277.420410] free_to_partial_list+0x515/0x5e0 [ 4277.421242] ? xfs_iext_remove+0x41a/0xa10 [xfs] [ 4277.422298] xfs_iext_remove+0x41a/0xa10 [xfs] [ 4277.423316] ? xfs_inodegc_worker+0xb4/0x1a0 [xfs] [ 4277.424383] xfs_bmap_del_extent_delay+0x4fe/0x7d0 [xfs] [ 4277.425490] __xfs_bunmapi+0x50d/0x840 [xfs] [ 4277.426445] xfs_itruncate_extents_flags+0x13a/0x490 [xfs] [ 4277.427553] xfs_inactive_truncate+0xa3/0x120 [xfs] [ 4277.428567] xfs_inactive+0x22d/0x290 [xfs] [ 4277.429500] xfs_inodegc_worker+0xb4/0x1a0 [xfs] [ 4277.430479] process_one_work+0x171/0x340 [ 4277.431227] worker_thread+0x277/0x390 [ 4277.431962] ? __pfx_worker_thread+0x10/0x10 [ 4277.432752] kthread+0xf0/0x120 [ 4277.433382] ? __pfx_kthread+0x10/0x10 [ 4277.434134] ret_from_fork+0x2d/0x50 [ 4277.434837] ? __pfx_kthread+0x10/0x10 [ 4277.435566] ret_from_fork_asm+0x1b/0x30 [ 4277.436280] </TASK>
--- mm/slab.h | 5 +++++ mm/slub.c | 9 ++++++++- 2 files changed, 13 insertions(+), 1 deletion(-)
mm/slab.h +5 -0
@@ -78,6 +78,11 @@ struct slab {struct {unsigned inuse:16 ;unsigned objects:15 ; +/* +* If slab debugging is enabled then the +* frozen bit can be reused to indicate +* that the slab was corrupted +*/ unsigned frozen:1 ; }; };
mm/slub.c +8 -1
@@ -1275,6 +1275,11 @@ static int check_slab(struct kmem_cache slab->inuse, slab->objects);return 0 ; } +if (slab->frozen) { +slab_err (s, slab,"Slab disabled since SLUB metadata consistency check failed" ); +return 0 ; + } +/* Slab_pad_check fixes things up after itself */ slab_pad_check (s, slab);return 1 ;
@@ -1463,6 +1468,7 @@ bad:slab_fix (s,"Marking all objects used" ); slab->inuse = slab->objects; slab->freelist =NULL ; + slab->frozen =1 ;/* mark consistency-failed slab as frozen */ }return false; }
@@ -2162,7 +2168,8 @@ static void *alloc_single_from_partial(s slab->inuse++;if (!alloc_debug_processing (s, slab, object, orig_size)) { -remove_partial (n, slab); +if (folio_test_slab (slab_folio (slab))) +remove_partial (n, slab);return NULL ; }
Greg Kroah-Hartman
maintainerPATCH 640/676 ceph: extract entity name from device id
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Patrick Donnelly <[email protected]>
commit 955710afcb3bb63e21e186451ed5eba85fa14d0b upstream.
Previously, the "name" in the new device syntax "<name>@<fsid>.<fsname>" was ignored because (presumably) tests were done using mount.ceph which also passed the entity name using "-o name=foo". If mounting is done without the mount.ceph helper, the new device id syntax fails to set the name properly.
--- fs/ceph/super.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
fs/ceph/super.c +9 -1
@@ -281,7 +281,9 @@ static int ceph_parse_new_source(const csize_t len;struct ceph_fsid fsid;struct ceph_parse_opts_ctx *pctx = fc->fs_private; +struct ceph_options *opts = pctx->copts;struct ceph_mount_options *fsopt = pctx->opts; +const char *name_start = dev_name;char *fsid_start, *fs_name_start;if (*dev_name_end !='=' ) {
@@ -292,8 +294,14 @@ static int ceph_parse_new_source(const c fsid_start =strchr (dev_name,'@' );if (!fsid_start)return invalfc (fc,"missing cluster fsid" ); - ++fsid_start;/* start of cluster fsid */ + len = fsid_start - name_start; +kfree (opts->name); + opts->name =kstrndup (name_start, len,GFP_KERNEL ); +if (!opts->name) +return -ENOMEM ; +dout ("using %s entity name" , opts->name); + ++fsid_start;/* start of cluster fsid */ fs_name_start =strchr (fsid_start,'.' );if (!fs_name_start)return invalfc (fc,"missing file system name" );
Greg Kroah-Hartman
maintainerPATCH 641/676 util_macros.h: fix/rework find_closest() macros
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexandru Ardelean <[email protected]>
commit bc73b4186736341ab5cd2c199da82db6e1134e13 upstream.
A bug was found in the find_closest() (find_closest_descending() is also affected after some testing), where for certain values with small progressions, the rounding (done by averaging 2 values) causes an incorrect index to be returned. The rounding issues occur for progressions of 1, 2 and 3. It goes away when the progression/interval between two values is 4 or larger.
It's particularly bad for progressions of 1. For example if there's an array of 'a = { 1, 2, 3 }', using 'find_closest(2, a ...)' would return 0 (the index of '1'), rather than returning 1 (the index of '2'). This means that for exact values (with a progression of 1), find_closest() will misbehave and return the index of the value smaller than the one we're searching for.
For progressions of 2 and 3, the exact values are obtained correctly; but values aren't approximated correctly (as one would expect). Starting with progressions of 4, all seems to be good (one gets what one would expect).
While one could argue that 'find_closest()' should not be used for arrays with progressions of 1 (i.e. '{1, 2, 3, ...}', the macro should still behave correctly.
The bug was found while testing the 'drivers/iio/adc/ad7606.c', specifically the oversampling feature.
For reference, the oversampling values are listed as:
static const unsigned int ad7606_oversampling_avail[7] = {
1, 2, 4, 8, 16, 32, 64,};
When doing:
1. $ echo 1 > /sys/bus/iio/devices/iio\:device0/oversampling_ratio
$ cat /sys/bus/iio/devices/iio\:device0/oversampling_ratio
1 # this is fine
2. $ echo 2 > /sys/bus/iio/devices/iio\:device0/oversampling_ratio
$ cat /sys/bus/iio/devices/iio\:device0/oversampling_ratio
1 # this is wrong; 2 should be returned here
3. $ echo 3 > /sys/bus/iio/devices/iio\:device0/oversampling_ratio
$ cat /sys/bus/iio/devices/iio\:device0/oversampling_ratio
2 # this is fine
4. $ echo 4 > /sys/bus/iio/devices/iio\:device0/oversampling_ratio
$ cat /sys/bus/iio/devices/iio\:device0/oversampling_ratio
4 # this is fine
And from here-on, the values are as correct (one gets what one would
expect.)While writing a kunit test for this bug, a peculiar issue was found for the array in the 'drivers/hwmon/ina2xx.c' & 'drivers/iio/adc/ina2xx-adc.c' drivers. While running the kunit test (for 'ina226_avg_tab' from these drivers):
* idx = find_closest([-1 to 2], ina226_avg_tab, ARRAY_SIZE(ina226_avg_tab));
This returns idx == 0, so value. * idx = find_closest(3, ina226_avg_tab, ARRAY_SIZE(ina226_avg_tab)); This returns idx == 0, value 1; and now one could argue whether 3 is closer to 4 or to 1. This quirk only appears for value '3' in this array, but it seems to be a another rounding issue.
* And from 4 onwards the 'find_closest'() works fine (one gets what one would expect).
This change reworks the find_closest() macros to also check the difference between the left and right elements when 'x'. If the distance to the right is smaller (than the distance to the left), the index is incremented by 1. This also makes redundant the need for using the DIV_ROUND_CLOSEST() macro.
In order to accommodate for any mix of negative + positive values, the internal variables '__fc_x', '__fc_mid_x', '__fc_left' & '__fc_right' are forced to 'long' type. This also addresses any potential bugs/issues with 'x' being of an unsigned type. In those situations any comparison between signed & unsigned would be promoted to a comparison between 2 unsigned numbers; this is especially annoying when '__fc_left' & '__fc_right' underflow.
The find_closest_descending() macro was also reworked and duplicated from the find_closest(), and it is being iterated in reverse. The main reason for this is to get the same indices as 'find_closest()' (but in reverse). The comparison for '__fc_right < __fc_left' favors going the array in ascending order.
For example for array '{ 1024, 512, 256, 128, 64, 16, 4, 1 }' and x = 3, we get:
__fc_mid_x = 2
__fc_left = -1
__fc_right = -2
Then '__fc_right < __fc_left' evaluates to true and '__fc_i++' becomes 7
which is not quite incorrect, but 3 is closer to 4 than to 1.This change has been validated with the kunit from the next patch.
--- include/linux/util_macros.h | 56 +++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 16 deletions(-)
include/linux/util_macros.h +40 -16
@@ -4,19 +4,6 @@#include <linux/math.h> -#define __find_closest (x, a, as, op) \ -({ \ - typeof(as) __fc_i, __fc_as = (as) - 1; \ - typeof(x) __fc_x = (x); \ - typeof(*a) const *__fc_a = (a); \ - for (__fc_i = 0; __fc_i < __fc_as; __fc_i++) { \ - if (__fc_x op DIV_ROUND_CLOSEST(__fc_a[__fc_i] + \ - __fc_a[__fc_i + 1], 2)) \ - break; \ - } \ - (__fc_i); \ -}) -/** * find_closest - locate the closest element in a sorted array * @x: The reference value.
@@ -25,8 +12,27 @@* @as: Size of 'a'. * * Returns the index of the element closest to 'x'. +* Note: If using an array of negative numbers (or mixed positive numbers), +* then be sure that 'x' is of a signed-type to get good results. */ -#define find_closest (x, a, as) __find_closest(x, a, as, <=) +#define find_closest (x, a, as) \ +({ \ + typeof(as) __fc_i, __fc_as = (as) - 1; \ + long __fc_mid_x, __fc_x = (x); \ + long __fc_left, __fc_right; \ + typeof(*a) const *__fc_a = (a); \ + for (__fc_i = 0; __fc_i < __fc_as; __fc_i++) { \ + __fc_mid_x = (__fc_a[__fc_i] + __fc_a[__fc_i + 1]) / 2; \ + if (__fc_x <= __fc_mid_x) { \ + __fc_left = __fc_x - __fc_a[__fc_i]; \ + __fc_right = __fc_a[__fc_i + 1] - __fc_x; \ + if (__fc_right < __fc_left) \ + __fc_i++; \ + break; \ + } \ + } \ + (__fc_i); \ +})/** * find_closest_descending - locate the closest element in a sorted array
@@ -36,9 +42,27 @@* @as: Size of 'a'. * * Similar to find_closest() but 'a' is expected to be sorted in descending -* order. +* order. The iteration is done in reverse order, so that the comparison +* of '__fc_right' & '__fc_left' also works for unsigned numbers. */ -#define find_closest_descending (x, a, as) __find_closest(x, a, as, >=) +#define find_closest_descending (x, a, as) \ +({ \ + typeof(as) __fc_i, __fc_as = (as) - 1; \ + long __fc_mid_x, __fc_x = (x); \ + long __fc_left, __fc_right; \ + typeof(*a) const *__fc_a = (a); \ + for (__fc_i = __fc_as; __fc_i >= 1; __fc_i--) { \ + __fc_mid_x = (__fc_a[__fc_i] + __fc_a[__fc_i - 1]) / 2; \ + if (__fc_x <= __fc_mid_x) { \ + __fc_left = __fc_x - __fc_a[__fc_i]; \ + __fc_right = __fc_a[__fc_i - 1] - __fc_x; \ + if (__fc_right < __fc_left) \ + __fc_i--; \ + break; \ + } \ + } \ + (__fc_i); \ +})/** * is_insidevar - check if the @ptr points inside the @var memory range.
Greg Kroah-Hartman
maintainerPATCH 642/676 scsi: ufs: exynos: Fix hibern8 notify callbacks
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Griffin <[email protected]>
commit ceef938bbf8b93ba3a218b4adc244cde94b582aa upstream.
v1 of the patch which introduced the ufshcd_vops_hibern8_notify() callback used a bool instead of an enum. In v2 this was updated to an enum based on the review feedback in [1].
ufs-exynos hibernate calls have always been broken upstream as it follows the v1 bool implementation.
--- drivers/ufs/host/ufs-exynos.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/ufs/host/ufs-exynos.c +8 -8
@@ -1228,12 +1228,12 @@ static void exynos_ufs_dev_hw_reset(struhci_writel (ufs,1 <<0 ,HCI_GPIO_OUT ); } -static void exynos_ufs_pre_hibern8 (struct ufs_hba *hba,u8 enter) +static void exynos_ufs_pre_hibern8 (struct ufs_hba *hba,enum uic_cmd_dme cmd) {struct exynos_ufs *ufs =ufshcd_get_variant (hba);struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr; -if (!enter) { +if (cmd ==UIC_CMD_DME_HIBER_EXIT ) {if (ufs->opts &EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL )exynos_ufs_disable_auto_ctrl_hcc (ufs);exynos_ufs_ungate_clks (ufs);
@@ -1261,11 +1261,11 @@ static void exynos_ufs_pre_hibern8(struc } } -static void exynos_ufs_post_hibern8 (struct ufs_hba *hba,u8 enter) +static void exynos_ufs_post_hibern8 (struct ufs_hba *hba,enum uic_cmd_dme cmd) {struct exynos_ufs *ufs =ufshcd_get_variant (hba); -if (!enter) { +if (cmd ==UIC_CMD_DME_HIBER_EXIT ) {u32 cur_mode =0 ;u32 pwrmode;
@@ -1284,7 +1284,7 @@ static void exynos_ufs_post_hibern8(struif (!(ufs->opts &EXYNOS_UFS_OPT_SKIP_CONNECTION_ESTAB ))exynos_ufs_establish_connt (ufs); - }else { + }else if (cmd ==UIC_CMD_DME_HIBER_ENTER ) { ufs->entry_hibern8_t =ktime_get ();exynos_ufs_gate_clks (ufs);if (ufs->opts &EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL )
@@ -1371,15 +1371,15 @@ static int exynos_ufs_pwr_change_notify( }static void exynos_ufs_hibern8_notify (struct ufs_hba *hba, -enum uic_cmd_dme enter, +enum uic_cmd_dme cmd,enum ufs_notify_change_status notify) {switch ((u8 )notify) {case PRE_CHANGE : -exynos_ufs_pre_hibern8 (hba, enter); +exynos_ufs_pre_hibern8 (hba, cmd);break ;case POST_CHANGE : -exynos_ufs_post_hibern8 (hba, enter); +exynos_ufs_post_hibern8 (hba, cmd);break ; } }
Greg Kroah-Hartman
maintainerPATCH 643/676 i3c: master: svc: Fix pm_runtime_set_suspended() with runtime pm enabled
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
commit 18599e93e4e814ce146186026c6abf83c14d5798 upstream.
It is not valid to call pm_runtime_set_suspended() for devices with runtime PM enabled because it returns -EAGAIN if it is enabled already and working. So, call pm_runtime_disable() before to fix it.
--- drivers/i3c/master/svc-i3c-master.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/i3c/master/svc-i3c-master.c +1 -1
@@ -1684,8 +1684,8 @@ static int svc_i3c_master_probe(struct p rpm_disable:pm_runtime_dont_use_autosuspend (&pdev->dev);pm_runtime_put_noidle (&pdev->dev); -pm_runtime_set_suspended (&pdev->dev);pm_runtime_disable (&pdev->dev); +pm_runtime_set_suspended (&pdev->dev); err_disable_clks:svc_i3c_master_unprepare_clks (master);
Greg Kroah-Hartman
maintainerPATCH 644/676 i3c: master: Fix miss free init_dyn_addr at i3c_master_put_i3c_addrs()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Li <[email protected]>
commit 3082990592f7c6d7510a9133afa46e31bbe26533 upstream.
if (dev->boardinfo && dev->boardinfo->init_dyn_addr)
^^^ here check "init_dyn_addr" i3c_bus_set_addr_slot_status(&master->bus, dev->info.dyn_addr, ...) ^^^^ free "dyn_addr"
Fix copy/paste error "dyn_addr" by replacing it with "init_dyn_addr".
--- drivers/i3c/master.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/i3c/master.c +1 -1
@@ -1293,7 +1293,7 @@ static void i3c_master_put_i3c_addrs(str I3C_ADDR_SLOT_FREE);if (dev->boardinfo && dev->boardinfo->init_dyn_addr) -i3c_bus_set_addr_slot_status (&master->bus, dev->info.dyn_addr, +i3c_bus_set_addr_slot_status (&master->bus, dev->boardinfo->init_dyn_addr,I3C_ADDR_SLOT_FREE ); }
Greg Kroah-Hartman
maintainerPATCH 645/676 PCI: keystone: Set mode as Root Complex for "ti,keystone-pcie" compatible
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kishon Vijay Abraham I <[email protected]>
commit 5a938ed9481b0c06cb97aec45e722a80568256fd upstream.
commit 23284ad677a9 ("PCI: keystone: Add support for PCIe EP in AM654x Platforms") introduced configuring "enum dw_pcie_device_mode" as part of device data ("struct ks_pcie_of_data"). However it failed to set the mode for "ti,keystone-pcie" compatible.
Since the mode defaults to "DW_PCIE_UNKNOWN_TYPE", the following error message is displayed for the v3.65a controller:
"INVALID device type 0"
Despite the driver probing successfully, the controller may not be functional in the Root Complex mode of operation.
So, set the mode as Root Complex for "ti,keystone-pcie" compatible to fix this.
--- drivers/pci/controller/dwc/pci-keystone.c | 1 + 1 file changed, 1 insertion(+)
drivers/pci/controller/dwc/pci-keystone.c +1 -0
@@ -1104,6 +1104,7 @@ static int ks_pcie_am654_set_mode(structstatic const struct ks_pcie_of_data ks_pcie_rc_of_data = { .host_ops = &ks_pcie_host_ops, + .mode =DW_PCIE_RC_TYPE , .version =DW_PCIE_VER_365A , };
Greg Kroah-Hartman
maintainerPATCH 646/676 PCI: keystone: Add link up check to ks_pcie_other_map_bus()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kishon Vijay Abraham I <[email protected]>
commit 9e9ec8d8692a6f64d81ef67d4fb6255af6be684b upstream.
K2G forwards the error triggered by a link-down state (e.g., no connected endpoint device) on the system bus for PCI configuration transactions; these errors are reported as an SError at system level, which is fatal and hangs the system.
So, apply fix similar to how it was done in the DesignWare Core driver commit 15b23906347c ("PCI: dwc: Add link up check in dw_child_pcie_ops.map_bus()").
--- drivers/pci/controller/dwc/pci-keystone.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/pci/controller/dwc/pci-keystone.c +11 -0
@@ -464,6 +464,17 @@ static void __iomem *ks_pcie_other_map_bstruct keystone_pcie *ks_pcie =to_keystone_pcie (pci);u32 reg; +/* +* Checking whether the link is up here is a last line of defense +* against platforms that forward errors on the system bus as +* SError upon PCI configuration transactions issued when the link +* is down. This check is racy by definition and does not stop +* the system from triggering an SError if the link goes down +* after this check is performed. +*/ +if (!dw_pcie_link_up (pci)) +return NULL ; + reg =CFG_BUS (bus->number) |CFG_DEVICE (PCI_SLOT (devfn)) |CFG_FUNC (PCI_FUNC (devfn));if (!pci_is_root_bus (bus->parent))
Greg Kroah-Hartman
maintainerPATCH 647/676 PCI: endpoint: Clear secondary (not primary) EPC in pci_epc_remove_epf()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zijun Hu <[email protected]>
commit 688d2eb4c6fcfdcdaed0592f9df9196573ff5ce2 upstream.
In addition to a primary endpoint controller, an endpoint function may be associated with a secondary endpoint controller, epf->sec_epc, to provide NTB (non-transparent bridge) functionality.
Previously, pci_epc_remove_epf() incorrectly cleared epf->epc instead of epf->sec_epc when removing from the secondary endpoint controller.
Extend the epc->list_lock coverage and clear either epf->epc or epf->sec_epc as indicated.
--- drivers/pci/endpoint/pci-epc-core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/pci/endpoint/pci-epc-core.c +3 -3
@@ -663,18 +663,18 @@ void pci_epc_remove_epf(struct pci_epc *if (!epc ||IS_ERR (epc) || !epf)return ; +mutex_lock (&epc->list_lock);if (type ==PRIMARY_INTERFACE ) { func_no = epf->func_no; list = &epf->list; + epf->epc =NULL ; }else { func_no = epf->sec_epc_func_no; list = &epf->sec_epc_list; + epf->sec_epc =NULL ; } - -mutex_lock (&epc->list_lock);clear_bit (func_no, &epc->function_num_map);list_del (list); - epf->epc =NULL ;mutex_unlock (&epc->list_lock); }EXPORT_SYMBOL_GPL (pci_epc_remove_epf);
Greg Kroah-Hartman
maintainerPATCH 648/676 fs/proc/kcore.c: Clear ret value in read_kcore_iter after successful iov_iter_zero
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Olsa <[email protected]>
commit 088f294609d8f8816dc316681aef2eb61982e0da upstream.
If iov_iter_zero succeeds after failed copy_from_kernel_nofault, we need to reset the ret value to zero otherwise it will be returned as final return value of read_kcore_iter.
This fixes objdump -d dump over /proc/kcore for me.
--- fs/proc/kcore.c | 1 + 1 file changed, 1 insertion(+)
fs/proc/kcore.c +1 -0
@@ -599,6 +599,7 @@ static ssize_t read_kcore_iter(struct ki ret = -EFAULT ; goto out; } + ret =0 ;/* * We know the bounce buffer is safe to copy from, so * use _copy_to_iter() directly.
Greg Kroah-Hartman
maintainerPATCH 649/676 thermal: int3400: Fix reading of current_uuid for active policy
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivas Pandruvada <[email protected]>
commit 7082503622986537f57bdb5ef23e69e70cfad881 upstream.
When the current_uuid attribute is set to the active policy UUID, reading back the same attribute is returning "INVALID" instead of the active policy UUID on some platforms before Ice Lake.
In platforms before Ice Lake, firmware provides a list of supported thermal policies. In this case, user space can select any of the supported thermal policies via a write to attribute "current_uuid".
In commit c7ff29763989 ("thermal: int340x: Update OS policy capability handshake")', the OS policy handshake was updated to support Ice Lake and later platforms and it treated priv->current_uuid_index=0 as invalid. However, priv->current_uuid_index=0 is for the active policy, only priv->current_uuid_index=-1 is invalid.
Fix this issue by updating the priv->current_uuid_index check.
--- drivers/thermal/intel/int340x_thermal/int3400_thermal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/thermal/intel/int340x_thermal/int3400_thermal.c +1 -1
@@ -144,7 +144,7 @@ static ssize_t current_uuid_show(structstruct int3400_thermal_priv *priv =dev_get_drvdata (dev);int i, length =0 ; -if (priv->current_uuid_index >0 ) +if (priv->current_uuid_index >=0 )return sprintf (buf,"%s\n" , int3400_thermal_uuids[priv->current_uuid_index]);
Greg Kroah-Hartman
maintainerPATCH 650/676 leds: flash: mt6360: Fix device_for_each_child_node() refcounting in error paths
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Carrasco <[email protected]>
commit 73b03b27736e440e3009fe1319cbc82d2cd1290c upstream.
The device_for_each_child_node() macro requires explicit calls to fwnode_handle_put() upon early exits to avoid memory leaks, and in this case the error paths are handled after jumping to 'out_flash_realease', which misses that required call to to decrement the refcount of the child node.
A more elegant and robust solution is using the scoped variant of the loop, which automatically handles such early exits.
Fix the child node refcounting in the error paths by using device_for_each_child_node_scoped().
--- drivers/leds/flash/leds-mt6360.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/leds/flash/leds-mt6360.c +1 -2
@@ -774,7 +774,6 @@ static void mt6360_v4l2_flash_release(ststatic int mt6360_led_probe (struct platform_device *pdev) {struct mt6360_priv *priv; -struct fwnode_handle *child;size_t count;int i =0 , ret;
@@ -801,7 +800,7 @@ static int mt6360_led_probe(struct platfreturn -ENODEV ; } -device_for_each_child_node (&pdev->dev, child) { +device_for_each_child_node_scoped (&pdev->dev, child) {struct mt6360_led *led = priv->leds + i;struct led_init_data init_data = { .fwnode = child, };u32 reg, led_color;
Greg Kroah-Hartman
maintainerPATCH 651/676 ovl: properly handle large files in ovl_security_fileattr
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleksandr Tymoshenko <[email protected]>
commit 3b6b99ef15ea37635604992ede9ebcccef38a239 upstream.
dentry_open in ovl_security_fileattr fails for any file larger than 2GB if open method of the underlying filesystem calls generic_file_open (e.g. fusefs).
The issue can be reproduce using the following script:
(passthrough_ll is an example app from libfuse).
$ D=/opt/test/mnt
$ mkdir -p ${D}/{source,base,top/uppr,top/work,ovlfs}
$ dd if=/dev/zero of=${D}/source/zero.bin bs=1G count=2
$ passthrough_ll -o source=${D}/source ${D}/base
$ mount -t overlay overlay \
-olowerdir=${D}/base,upperdir=${D}/top/uppr,workdir=${D}/top/work \
${D}/ovlfs
$ chmod 0777 ${D}/mnt/ovlfs/zero.binRunning this script results in "Value too large for defined data type" error message from chmod.
--- fs/overlayfs/inode.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
fs/overlayfs/inode.c +6 -1
@@ -741,8 +741,13 @@ static int ovl_security_fileattr(const sstruct file *file;unsigned int cmd;int err; +unsigned int flags; - file =dentry_open (realpath,O_RDONLY ,current_cred ()); + flags =O_RDONLY ; +if (force_o_largefile ()) + flags |=O_LARGEFILE ; + + file =dentry_open (realpath, flags,current_cred ());if (IS_ERR (file))return PTR_ERR (file);
Greg Kroah-Hartman
maintainerPATCH 652/676 dm: Fix typo in error message
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ssuhung Yeh <[email protected]>
commit 2deb70d3e66d538404d9e71bff236e6d260da66e upstream.
Remove the redundant "i" at the beginning of the error message. This "i" came from commit 1c1318866928 ("dm: prefer
'"%s...", __func__'"), the "i" is accidentally left.
--- drivers/md/persistent-data/dm-space-map-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/md/persistent-data/dm-space-map-common.c +1 -1
@@ -51,7 +51,7 @@ static int index_check(const struct dm_block_validator *v, block_size -sizeof (__le32), INDEX_CSUM_XOR));if (csum_disk != mi_le->csum) { -DMERR_LIMIT ("i%s failed: csum %u != wanted %u" , __func__, +DMERR_LIMIT ("%s failed: csum %u != wanted %u" , __func__,le32_to_cpu (csum_disk),le32_to_cpu (mi_le->csum));return -EILSEQ ; }
Signature · 1 line
2.47.1
Greg Kroah-Hartman
maintainerPATCH 653/676 dm thin: Add missing destroy_work_on_stack()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuan Can <[email protected]>
commit e74fa2447bf9ed03d085b6d91f0256cc1b53f1a8 upstream.
This commit add missed destroy_work_on_stack() operations for pw->worker in pool_work_wait().
--- drivers/md/dm-thin.c | 1 + 1 file changed, 1 insertion(+)
drivers/md/dm-thin.c +1 -0
@@ -2486,6 +2486,7 @@ static void pool_work_wait(struct pool_winit_completion (&pw->complete);queue_work (pool->wq, &pw->worker);wait_for_completion (&pw->complete); +destroy_work_on_stack (&pw->worker); }/*----------------------------------------------------------------*/
Greg Kroah-Hartman
maintainerPATCH 654/676 PCI: of_property: Assign PCI instead of CPU bus address to dynamic PCI nodes
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrea della Porta <[email protected]>
commit 5e316d34b53039346e252d0019e2f4167af2c0ef upstream.
When populating "ranges" property for a PCI bridge or endpoint, of_pci_prop_ranges() incorrectly uses the CPU address of the resource. In such PCI nodes, the window should instead be in PCI address space. Call pci_bus_address() on the resource in order to obtain the PCI bus address.
[Previous discussion at:
https://lore.kernel.org/all/8b4fa91380fc4754ea80f47330c613e4f6b6592c.1724159867.git.andrea.porta@suse.com/]
--- drivers/pci/of_property.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pci/of_property.c +1 -1
@@ -126,7 +126,7 @@ static int of_pci_prop_ranges(struct pci_dev *pdev, struct of_changeset *ocs,if (of_pci_get_addr_flags (&res[j], &flags))continue ; - val64 = res[j].start; + val64 =pci_bus_address (pdev, &res[j] - pdev->resource);of_pci_set_address (pdev, rp[i].parent_addr, val64,0 , flags, false);if (pci_is_bridge (pdev)) {
Signature · 1 line
2.47.1
Greg Kroah-Hartman
maintainerPATCH 655/676 PCI: rockchip-ep: Fix address translation unit programming
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Damien Le Moal <[email protected]>
commit 64f093c4d99d797b68b407a9d8767aadc3e3ea7a upstream.
The Rockchip PCIe endpoint controller handles PCIe transfers addresses by masking the lower bits of the programmed PCI address and using the same number of lower bits masked from the CPU address space used for the mapping. For a PCI mapping of <size> bytes starting from <pci_addr>, the number of bits masked is the number of address bits changing in the address range [pci_addr..pci_addr + size - 1].
However, rockchip_pcie_prog_ep_ob_atu() calculates num_pass_bits only using the size of the mapping, resulting in an incorrect number of mask bits depending on the value of the PCI address to map.
Fix this by introducing the helper function rockchip_pcie_ep_ob_atu_num_bits() to correctly calculate the number of mask bits to use to program the address translation unit. The number of mask bits is calculated depending on both the PCI address and size of the mapping, and clamped between 8 and 20 using the macros ROCKCHIP_PCIE_AT_MIN_NUM_BITS and ROCKCHIP_PCIE_AT_MAX_NUM_BITS. As defined in the Rockchip RK3399 TRM V1.3 Part2, Sections 17.5.5.1.1 and 17.6.8.2.1, this clamping is necessary because:
1) The lower 8 bits of the PCI address to be mapped by the outbound region are ignored. So a minimum of 8 address bits are needed and imply that the PCI address must be aligned to 256.
2) The outbound memory regions are 1MB in size. So while we can specify up to 63-bits for the PCI address (num_bits filed uses bits 0 to 5 of the outbound address region 0 register), we must limit the number of valid address bits to 20 to match the memory window maximum size (1 << 20 = 1MB).
--- drivers/pci/controller/pcie-rockchip-ep.c | 16 +++++++++++++--- drivers/pci/controller/pcie-rockchip.h | 4 ++++ 2 files changed, 17 insertions(+), 3 deletions(-)
drivers/pci/controller/pcie-rockchip-ep.c +13 -3
@@ -63,15 +63,25 @@ static void rockchip_pcie_clear_ep_ob_at ROCKCHIP_PCIE_AT_OB_REGION_DESC1(region)); } +static int rockchip_pcie_ep_ob_atu_num_bits (struct rockchip_pcie *rockchip, +u64 pci_addr,size_t size) +{ +int num_pass_bits =fls64 (pci_addr ^ (pci_addr + size -1 )); + +return clamp (num_pass_bits, +ROCKCHIP_PCIE_AT_MIN_NUM_BITS , +ROCKCHIP_PCIE_AT_MAX_NUM_BITS ); +} +static void rockchip_pcie_prog_ep_ob_atu (struct rockchip_pcie *rockchip,u8 fn,u32 r,u64 cpu_addr,u64 pci_addr,size_t size) { -int num_pass_bits =fls64 (size -1 ); +int num_pass_bits;u32 addr0, addr1, desc0; -if (num_pass_bits <8 ) - num_pass_bits =8 ; + num_pass_bits =rockchip_pcie_ep_ob_atu_num_bits (rockchip, + pci_addr, size); addr0 = ((num_pass_bits -1 ) &PCIE_CORE_OB_REGION_ADDR0_NUM_BITS ) | (lower_32_bits (pci_addr) &PCIE_CORE_OB_REGION_ADDR0_LO_ADDR );
drivers/pci/controller/pcie-rockchip.h +4 -0
@@ -245,6 +245,10 @@ (PCIE_EP_PF_CONFIG_REGS_BASE + (((fn) << 12) & GENMASK(19, 12)))#define ROCKCHIP_PCIE_EP_VIRT_FUNC_BASE (fn) \ (PCIE_EP_PF_CONFIG_REGS_BASE + 0x10000 + (((fn) << 12) & GENMASK(19, 12))) + +#define ROCKCHIP_PCIE_AT_MIN_NUM_BITS 8 +#define ROCKCHIP_PCIE_AT_MAX_NUM_BITS 20 +#define ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR0 (fn, bar) \ (PCIE_CORE_AXI_CONF_BASE + 0x0828 + (fn) * 0x0040 + (bar) * 0x0008)#define ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR1 (fn, bar) \
Greg Kroah-Hartman
maintainerPATCH 656/676 nfsd: make sure exp active before svc_export_show
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Erkun <[email protected]>
commit be8f982c369c965faffa198b46060f8853e0f1f0 upstream.
The function e_show was called with protection from RCU. This only ensures that exp will not be freed. Therefore, the reference count for exp can drop to zero, which will trigger a refcount use-after-free warning when exp_get is called. To resolve this issue, use cache_get_rcu to ensure that exp remains active.
------------[ cut here ]------------ refcount_t: addition on 0; use-after-free. WARNING: CPU: 3 PID: 819 at lib/refcount.c:25 refcount_warn_saturate+0xb1/0x120 CPU: 3 UID: 0 PID: 819 Comm: cat Not tainted 6.12.0-rc3+ #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.1-2.fc37 04/01/2014 RIP: 0010:refcount_warn_saturate+0xb1/0x120 ... Call Trace: <TASK> e_show+0x20b/0x230 [nfsd] seq_read_iter+0x589/0x770 seq_read+0x1e5/0x270 vfs_read+0x125/0x530 ksys_read+0xc1/0x160 do_syscall_64+0x5f/0x170 entry_SYSCALL_64_after_hwframe+0x76/0x7e
--- fs/nfsd/export.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
fs/nfsd/export.c +4 -1
@@ -1385,9 +1385,12 @@ static int e_show(struct seq_file *m, voreturn 0 ; } -exp_get (exp); +if (!cache_get_rcu (&exp->h)) +return 0 ; +if (cache_check (cd, &exp->h,NULL ))return 0 ; +exp_put (exp);return svc_export_show (m, cd, cp); }
Greg Kroah-Hartman
maintainerPATCH 657/676 nfsd: fix nfs4_openowner leak when concurrent nfsd4_open occur
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Erkun <[email protected]>
commit 98100e88dd8865999dc6379a3356cd799795fe7b upstream.
The action force umount(umount -f) will attempt to kill all rpc_task even umount operation may ultimately fail if some files remain open. Consequently, if an action attempts to open a file, it can potentially send two rpc_task to nfs server.
NFS CLIENT
thread1 thread2open("file")
...nfs4_do_open
_nfs4_do_open
_nfs4_open_and_get_state
_nfs4_proc_open
nfs4_run_open_task
/* rpc_task1 */
rpc_run_task
rpc_wait_for_completion_task
umount -f
nfs_umount_begin
rpc_killall_tasks
rpc_signal_task
rpc_task1 been wakeup
and return -512
_nfs4_do_open // while loop
...
nfs4_run_open_task
/* rpc_task2 */
rpc_run_task
rpc_wait_for_completion_taskWhile processing an open request, nfsd will first attempt to find or allocate an nfs4_openowner. If it finds an nfs4_openowner that is not marked as NFS4_OO_CONFIRMED, this nfs4_openowner will released. Since two rpc_task can attempt to open the same file simultaneously from the client to server, and because two instances of nfsd can run concurrently, this situation can lead to lots of memory leak. Additionally, when we echo 0 to /proc/fs/nfsd/threads, warning will be triggered.
NFS SERVER
nfsd1 nfsd2 echo 0 > /proc/fs/nfsd/threads
nfsd4_open
nfsd4_process_open1
find_or_alloc_open_stateowner
// alloc oo1, stateid1
nfsd4_open
nfsd4_process_open1
find_or_alloc_open_stateowner
// find oo1, without NFS4_OO_CONFIRMED
release_openowner
unhash_openowner_locked
list_del_init(&oo->oo_perclient)
// cannot find this oo
// from client, LEAK!!!
alloc_stateowner // alloc oo2 nfsd4_process_open2
init_open_stateid
// associate oo1
// with stateid1, stateid1 LEAK!!!
nfs4_get_vfs_file
// alloc nfsd_file1 and nfsd_file_mark1
// all LEAK!!!
nfsd4_process_open2
...
write_threads
...
nfsd_destroy_serv
nfsd_shutdown_net
nfs4_state_shutdown_net
nfs4_state_destroy_net
destroy_client
__destroy_client
// won't find oo1!!!
nfsd_shutdown_generic
nfsd_file_cache_shutdown
kmem_cache_destroy
for nfsd_file_slab
and nfsd_file_mark_slab
// bark since nfsd_file1
// and nfsd_file_mark1
// still alive=======================================================================
BUG nfsd_file (Not tainted): Objects remaining in nfsd_file on __kmem_cache_shutdown()
-----------------------------------------------------------------------
Slab 0xffd4000004438a80 objects=34 used=1 fp=0xff11000110e2ad28 flags=0x17ffffc0000240(workingset|head|node=0|zone=2|lastcpupid=0x1fffff)
CPU: 4 UID: 0 PID: 757 Comm: sh Not tainted 6.12.0-rc6+ #19 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.1-2.fc37 04/01/2014 Call Trace: <TASK> dump_stack_lvl+0x53/0x70 slab_err+0xb0/0xf0 __kmem_cache_shutdown+0x15c/0x310 kmem_cache_destroy+0x66/0x160 nfsd_file_cache_shutdown+0xac/0x210 [nfsd] nfsd_destroy_serv+0x251/0x2a0 [nfsd] nfsd_svc+0x125/0x1e0 [nfsd] write_threads+0x16a/0x2a0 [nfsd] nfsctl_transaction_write+0x74/0xa0 [nfsd] vfs_write+0x1ae/0x6d0 ksys_write+0xc1/0x160 do_syscall_64+0x5f/0x170 entry_SYSCALL_64_after_hwframe+0x76/0x7e
Disabling lock debugging due to kernel taint
Object 0xff11000110e2ac38 @offset=3128
Allocated in nfsd_file_do_acquire+0x20f/0xa30 [nfsd] age=1635 cpu=3 pid=800
nfsd_file_do_acquire+0x20f/0xa30 [nfsd] nfsd_file_acquire_opened+0x5f/0x90 [nfsd] nfs4_get_vfs_file+0x4c9/0x570 [nfsd] nfsd4_process_open2+0x713/0x1070 [nfsd] nfsd4_open+0x74b/0x8b0 [nfsd] nfsd4_proc_compound+0x70b/0xc20 [nfsd] nfsd_dispatch+0x1b4/0x3a0 [nfsd] svc_process_common+0x5b8/0xc50 [sunrpc] svc_process+0x2ab/0x3b0 [sunrpc] svc_handle_xprt+0x681/0xa20 [sunrpc] nfsd+0x183/0x220 [nfsd] kthread+0x199/0x1e0 ret_from_fork+0x31/0x60 ret_from_fork_asm+0x1a/0x30
Add nfs4_openowner_unhashed to help found unhashed nfs4_openowner, and break nfsd4_open process to fix this problem.
--- fs/nfsd/nfs4state.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
fs/nfsd/nfs4state.c +19 -0
@@ -1625,6 +1625,14 @@ static void release_open_stateid(structfree_ol_stateid_reaplist (&reaplist); } +static bool nfs4_openowner_unhashed (struct nfs4_openowner *oo) +{ +lockdep_assert_held (&oo->oo_owner.so_client->cl_lock); + +return list_empty (&oo->oo_owner.so_strhash) && +list_empty (&oo->oo_perclient); +} +static void unhash_openowner_locked (struct nfs4_openowner *oo) {struct nfs4_client *clp = oo->oo_owner.so_client;
@@ -4632,6 +4640,12 @@ retry:spin_lock (&oo->oo_owner.so_client->cl_lock);spin_lock (&fp->fi_lock); +if (nfs4_openowner_unhashed (oo)) { +mutex_unlock (&stp->st_mutex); + stp =NULL ; + goto out_unlock; + } + retstp =nfsd4_find_existing_open (fp, open);if (retstp) goto out_unlock;
@@ -5751,6 +5765,11 @@ nfsd4_process_open2(struct svc_rqst *rqsif (!stp) { stp =init_open_stateid (fp, open); +if (!stp) { + status = nfserr_jukebox; + goto out; + } +if (!open->op_stp) new_stp = true; }
Greg Kroah-Hartman
maintainerPATCH 658/676 iio: accel: kx022a: Fix raw read format
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matti Vaittinen <[email protected]>
commit b7d2bc99b3bdc03fff9b416dd830632346d83530 upstream.
The KX022A provides the accelerometer data in two subsequent registers. The registers are laid out so that the value obtained via bulk-read of these registers can be interpreted as signed 16-bit little endian value. The read value is converted to cpu_endianes and stored into 32bit integer. The le16_to_cpu() casts value to unsigned 16-bit value, and when this is assigned to 32-bit integer the resulting value will always be positive.
This has not been a problem to users (at least not all users) of the sysfs interface, who know the data format based on the scan info and who have converted the read value back to 16-bit signed value. This isn't compliant with the ABI however.
This, however, will be a problem for those who use the in-kernel interfaces, especially the iio_read_channel_processed_scale().
The iio_read_channel_processed_scale() performs multiplications to the returned (always positive) raw value, which will cause strange results when the data from the sensor has been negative.
Fix the read_raw format by casting the result of the le_to_cpu() to signed 16-bit value before assigning it to the integer. This will make the negative readings to be correctly reported as negative.
This fix will be visible to users by changing values returned via sysfs to appear in correct (negative) format.
--- drivers/iio/accel/kionix-kx022a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/accel/kionix-kx022a.c +1 -1
@@ -475,7 +475,7 @@ static int kx022a_get_axis(struct kx022aif (ret)return ret; - *val =le16_to_cpu (data->buffer[0 ]); + *val = (s16 )le16_to_cpu (data->buffer[0 ]);return IIO_VAL_INT ; }
Greg Kroah-Hartman
maintainerPATCH 659/676 iio: Fix fwnode_handle in __fwnode_iio_channel_get_by_name()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zicheng Qu <[email protected]>
commit 3993ca4add248f0f853f54f9273a7de850639f33 upstream.
In the fwnode_iio_channel_get_by_name(), iterating over parent nodes to acquire IIO channels via fwnode_for_each_parent_node(). The variable chan was mistakenly attempted on the original node instead of the current parent node. This patch corrects the logic to ensure that __fwnode_iio_channel_get_by_name() is called with the correct parent node.
--- drivers/iio/inkern.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/inkern.c +1 -1
@@ -277,7 +277,7 @@ struct iio_channel *fwnode_iio_channel_greturn ERR_PTR (-ENODEV ); } - chan =__fwnode_iio_channel_get_by_name (fwnode, name); + chan =__fwnode_iio_channel_get_by_name (parent, name);if (!IS_ERR (chan) ||PTR_ERR (chan) != -ENODEV ) {fwnode_handle_put (parent);return chan;
Greg Kroah-Hartman
maintainerPATCH 660/676 iio: adc: ad7923: Fix buffer overflow for tx_buf and ring_xfer
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nuno Sa <[email protected]>
commit 3a4187ec454e19903fd15f6e1825a4b84e59a4cd upstream.
The AD7923 was updated to support devices with 8 channels, but the size of tx_buf and ring_xfer was not increased accordingly, leading to a potential buffer overflow in ad7923_update_scan_mode().
--- drivers/iio/adc/ad7923.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/iio/adc/ad7923.c +2 -2
@@ -48,7 +48,7 @@struct ad7923_state {struct spi_device *spi; -struct spi_transfer ring_xfer[5 ]; +struct spi_transfer ring_xfer[9 ];struct spi_transfer scan_single_xfer[2 ];struct spi_message ring_msg;struct spi_message scan_single_msg;
@@ -64,7 +64,7 @@ struct ad7923_state {* Length = 8 channels + 4 extra for 8 byte timestamp */ __be16 rx_buf[12 ]__aligned(IIO_DMA_MINALIGN) ; -__be16 tx_buf[4 ]; +__be16 tx_buf[8 ]; };struct ad7923_chip_info {
Greg Kroah-Hartman
maintainerPATCH 661/676 iio: gts: fix infinite loop for gain_to_scaletables()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zicheng Qu <[email protected]>
commit 7452f8a0814bb73f739ee0dab60f099f3361b151 upstream.
In iio_gts_build_avail_time_table(), it is checked that gts->num_itime is non-zero, but gts->num_itime is not checked in gain_to_scaletables(). The variable time_idx is initialized as gts->num_itime - 1. This implies that time_idx might initially be set to -1 (0 - 1 = -1). Consequently, using while (time_idx--) could lead to an infinite loop.
--- drivers/iio/industrialio-gts-helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/industrialio-gts-helper.c +1 -1
@@ -205,7 +205,7 @@ static int gain_to_scaletables(struct iimemcpy (all_gains, gains[time_idx], gain_bytes); new_idx = gts->num_hwgain; -while (time_idx--) { +while (time_idx-- >0 ) {for (j =0 ; j < gts->num_hwgain; j++) {int candidate = gains[time_idx][j];int chk;
Greg Kroah-Hartman
maintainerPATCH 662/676 powerpc: Fix stack protector Kconfig test for clang
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nathan Chancellor <[email protected]>
commit 46e1879deea22eed31e9425d58635895fc0e8040 upstream.
Clang's in-progress per-task stack protector support [1] does not work with the current Kconfig checks because '-mstack-protector-guard-offset' is not provided, unlike all other architecture Kconfig checks.
$ fd Kconfig -x rg -l mstack-protector-guard-offset ./arch/arm/Kconfig ./arch/riscv/Kconfig ./arch/arm64/Kconfig
This produces an error from clang, which is interpreted as the flags not being supported at all when they really are.
$ clang --target=powerpc64-linux-gnu \
-mstack-protector-guard=tls \
-mstack-protector-guard-reg=r13 \
-c -o /dev/null -x c /dev/null
clang: error: '-mstack-protector-guard=tls' is used without '-mstack-protector-guard-offset', and there is no defaultThis argument will always be provided by the build system, so mirror other architectures and use '-mstack-protector-guard-offset=0' for testing support, which fixes the issue for clang and does not regress support with GCC.
Even with the first problem addressed, the 32-bit test continues to fail because Kbuild uses the powerpc64le-linux-gnu target for clang and nothing flips the target to 32-bit, resulting in an error about an invalid register valid:
$ clang --target=powerpc64le-linux-gnu \
-mstack-protector-guard=tls
-mstack-protector-guard-reg=r2 \
-mstack-protector-guard-offset=0 \
-x c -c -o /dev/null /dev/null
clang: error: invalid value 'r2' in 'mstack-protector-guard-reg=', expected one of: r13While GCC allows arbitrary registers, the implementation of '-mstack-protector-guard=tls' in LLVM shares the same code path as the user space thread local storage implementation, which uses a fixed register (2 for 32-bit and 13 for 62-bit), so the command line parsing enforces this limitation.
Use the Kconfig macro '$(m32-flag)', which expands to '-m32' when supported, in the stack protector support cc-option call to properly switch the target to a 32-bit one, which matches what happens in Kbuild. While the 64-bit macro does not strictly need it, add the equivalent 64-bit option for symmetry.
--- arch/powerpc/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/powerpc/Kconfig +2 -2
@@ -271,8 +271,8 @@ config PPC select HAVE_RSEQ select HAVE_SETUP_PER_CPU_AREA if PPC64 select HAVE_SOFTIRQ_ON_OWN_STACK - select HAVE_STACKPROTECTOR if PPC32 && $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r2) - select HAVE_STACKPROTECTOR if PPC64 && $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r13) + select HAVE_STACKPROTECTOR if PPC32 && $(cc-option,$(m32-flag) -mstack-protector-guard=tls -mstack-protector-guard-reg=r2 -mstack-protector-guard-offset=0) + select HAVE_STACKPROTECTOR if PPC64 && $(cc-option,$(m64-flag) -mstack-protector-guard=tls -mstack-protector-guard-reg=r13 -mstack-protector-guard-offset=0) select HAVE_STATIC_CALL if PPC32 select HAVE_SYSCALL_TRACEPOINTS select HAVE_VIRT_CPU_ACCOUNTING
Greg Kroah-Hartman
maintainerPATCH 663/676 powerpc: Adjust adding stack protector flags to KBUILD_CLAGS for clang
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nathan Chancellor <[email protected]>
commit bee08a9e6ab03caf14481d97b35a258400ffab8f upstream.
After fixing the HAVE_STACKPROTECTER checks for clang's in-progress per-task stack protector support [1], the build fails during prepare0 because '-mstack-protector-guard-offset' has not been added to KBUILD_CFLAGS yet but the other '-mstack-protector-guard' flags have.
clang: error: '-mstack-protector-guard=tls' is used without '-mstack-protector-guard-offset', and there is no default
clang: error: '-mstack-protector-guard=tls' is used without '-mstack-protector-guard-offset', and there is no default make[4]: *** [scripts/Makefile.build:229: scripts/mod/empty.o] Error 1
make[4]: *** [scripts/Makefile.build:102: scripts/mod/devicetable-offsets.s] Error 1
Mirror other architectures and add all '-mstack-protector-guard' flags to KBUILD_CFLAGS atomically during stack_protector_prepare, which resolves the issue and allows clang's implementation to fully work with the kernel.
--- arch/powerpc/Makefile | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)
arch/powerpc/Makefile +4 -9
@@ -89,13 +89,6 @@ KBUILD_AFLAGS += -m$(BITS) KBUILD_LDFLAGS += -m elf$(BITS)$(LDEMULATION) endif -cflags-$(CONFIG_STACKPROTECTOR) += -mstack-protector-guard=tls -ifdef CONFIG_PPC64 -cflags-$(CONFIG_STACKPROTECTOR) += -mstack-protector-guard-reg=r13 -else -cflags-$(CONFIG_STACKPROTECTOR) += -mstack-protector-guard-reg=r2 -endif - LDFLAGS_vmlinux-y := -Bstatic LDFLAGS_vmlinux-$(CONFIG_RELOCATABLE) := -pie LDFLAGS_vmlinux-$(CONFIG_RELOCATABLE) += -z notext
@@ -389,9 +382,11 @@ prepare: stack_protector_prepare PHONY += stack_protector_prepare stack_protector_prepare: prepare0 ifdef CONFIG_PPC64 - $(eval KBUILD_CFLAGS += -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "PACA_CANARY") print $$3;}' include/generated/asm-offsets.h)) + $(eval KBUILD_CFLAGS += -mstack-protector-guard=tls -mstack-protector-guard-reg=r13 \ + -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "PACA_CANARY") print $$3;}' include/generated/asm-offsets.h)) else - $(eval KBUILD_CFLAGS += -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "TASK_CANARY") print $$3;}' include/generated/asm-offsets.h)) + $(eval KBUILD_CFLAGS += -mstack-protector-guard=tls -mstack-protector-guard-reg=r2 \ + -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "TASK_CANARY") print $$3;}' include/generated/asm-offsets.h)) endif endif
Greg Kroah-Hartman
maintainerPATCH 664/676 btrfs: dont BUG_ON on ENOMEM from btrfs_lookup_extent_info() in walk_down_proc()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
commit a580fb2c3479d993556e1c31b237c9e5be4944a3 upstream.
We handle errors here properly, ENOMEM isn't fatal, return the error.
--- fs/btrfs/extent-tree.c | 1 - 1 file changed, 1 deletion(-)
fs/btrfs/extent-tree.c +0 -1
@@ -5170,7 +5170,6 @@ static noinline int walk_down_proc(struc eb->start, level,1 , &wc->refs[level], &wc->flags[level]); -BUG_ON (ret == -ENOMEM );if (ret)return ret;if (unlikely (wc->refs[level] ==0 )) {
Greg Kroah-Hartman
maintainerPATCH 665/676 tpm: Lock TPM chip in tpm_pm_suspend() first
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jarkko Sakkinen <[email protected]>
commit 9265fed6db601ee2ec47577815387458ef4f047a upstream.
Setting TPM_CHIP_FLAG_SUSPENDED in the end of tpm_pm_suspend() can be racy according, as this leaves window for tpm_hwrng_read() to be called while the operation is in progress. The recent bug report gives also evidence of this behaviour.
Aadress this by locking the TPM chip before checking any chip->flags both in tpm_pm_suspend() and tpm_hwrng_read(). Move TPM_CHIP_FLAG_SUSPENDED check inside tpm_get_random() so that it will be always checked only when the lock is reserved.
--- drivers/char/tpm/tpm-chip.c | 4 ---- drivers/char/tpm/tpm-interface.c | 29 +++++++++++++++++++++-------- 2 files changed, 21 insertions(+), 12 deletions(-)
drivers/char/tpm/tpm-chip.c +0 -4
@@ -519,10 +519,6 @@ static int tpm_hwrng_read(struct hwrng * { struct tpm_chip *chip = container_of(rng, struct tpm_chip, hwrng); -/* Give back zero bytes, as TPM chip has not yet fully resumed: */ -if (chip->flags &TPM_CHIP_FLAG_SUSPENDED ) -return 0 ; -return tpm_get_random (chip, data, max); }
drivers/char/tpm/tpm-interface.c +21 -8
@@ -394,6 +394,13 @@ int tpm_pm_suspend(struct device *dev)if (!chip)return -ENODEV ; + rc =tpm_try_get_ops (chip); +if (rc) { +/* Can be safely set out of locks, as no action cannot race: */ + chip->flags |=TPM_CHIP_FLAG_SUSPENDED ; + goto out; + } +if (chip->flags &TPM_CHIP_FLAG_ALWAYS_POWERED ) goto suspended;
@@ -401,19 +408,18 @@ int tpm_pm_suspend(struct device *dev) !pm_suspend_via_firmware()) goto suspended; - rc =tpm_try_get_ops (chip); -if (!rc) { -if (chip->flags &TPM_CHIP_FLAG_TPM2 ) -tpm2_shutdown (chip,TPM2_SU_STATE ); -else - rc =tpm1_pm_suspend (chip, tpm_suspend_pcr); - -tpm_put_ops (chip); +if (chip->flags &TPM_CHIP_FLAG_TPM2 ) { +tpm2_shutdown (chip,TPM2_SU_STATE ); + goto suspended; } + rc =tpm1_pm_suspend (chip, tpm_suspend_pcr); + suspended: chip->flags |=TPM_CHIP_FLAG_SUSPENDED ; +tpm_put_ops (chip); +out:if (rc)dev_err (dev,"Ignoring error %d while suspending\n" , rc);return 0 ;
@@ -462,11 +468,18 @@ int tpm_get_random(struct tpm_chip *chipif (!chip)return -ENODEV ; +/* Give back zero bytes, as TPM chip has not yet fully resumed: */ +if (chip->flags &TPM_CHIP_FLAG_SUSPENDED ) { + rc =0 ; + goto out; + } +if (chip->flags &TPM_CHIP_FLAG_TPM2 ) rc =tpm2_get_random (chip, out, max);else rc =tpm1_get_random (chip, out, max); +out:tpm_put_ops (chip);return rc; }
Greg Kroah-Hartman
maintainerPATCH 666/676 udmabuf: use vmf_insert_pfn and VM_PFNMAP for handling mmap
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vivek Kasireddy <[email protected]>
commit 7d79cd784470395539bda91bf0b3505ff5b2ab6d upstream.
Add VM_PFNMAP to vm_flags in the mmap handler to ensure that the mappings would be managed without using struct page.
And, in the vm_fault handler, use vmf_insert_pfn to share the page's pfn to userspace instead of directly sharing the page (via struct page *).
--- drivers/dma-buf/udmabuf.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/dma-buf/udmabuf.c +5 -3
@@ -35,12 +35,13 @@ static vm_fault_t udmabuf_vm_fault(strucstruct vm_area_struct *vma = vmf->vma;struct udmabuf *ubuf = vma->vm_private_data;pgoff_t pgoff = vmf->pgoff; +unsigned long pfn;if (pgoff >= ubuf->pagecount)return VM_FAULT_SIGBUS ; - vmf->page = ubuf->pages[pgoff]; -get_page (vmf->page); -return 0 ; + + pfn =page_to_pfn (ubuf->pages[pgoff]); +return vmf_insert_pfn (vma, vmf->address, pfn); }static const struct vm_operations_struct udmabuf_vm_ops = {
@@ -56,6 +57,7 @@ static int mmap_udmabuf(struct dma_buf * vma->vm_ops = &udmabuf_vm_ops; vma->vm_private_data = ubuf; +vm_flags_set (vma,VM_PFNMAP |VM_DONTEXPAND |VM_DONTDUMP );return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 667/676 drm/sti: avoid potential dereference of error pointers in sti_hqvdp_atomic_check
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Ke <[email protected]>
commit c1ab40a1fdfee732c7e6ff2fb8253760293e47e8 upstream.
The return value of drm_atomic_get_crtc_state() needs to be checked. To avoid use of error pointer 'crtc_state' in case of the failure.
--- drivers/gpu/drm/sti/sti_hqvdp.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/sti/sti_hqvdp.c +3 -0
@@ -1037,6 +1037,9 @@ static int sti_hqvdp_atomic_check(structreturn 0 ; crtc_state =drm_atomic_get_crtc_state (state, crtc); +if (IS_ERR (crtc_state)) +return PTR_ERR (crtc_state); + mode = &crtc_state->mode; dst_x = new_plane_state->crtc_x; dst_y = new_plane_state->crtc_y;
Greg Kroah-Hartman
maintainerPATCH 668/676 drm/sti: avoid potential dereference of error pointers in sti_gdp_atomic_check
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Ke <[email protected]>
commit e965e771b069421c233d674c3c8cd8c7f7245f42 upstream.
The return value of drm_atomic_get_crtc_state() needs to be checked. To avoid use of error pointer 'crtc_state' in case of the failure.
--- drivers/gpu/drm/sti/sti_gdp.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/sti/sti_gdp.c +3 -0
@@ -638,6 +638,9 @@ static int sti_gdp_atomic_check(struct d mixer =to_sti_mixer (crtc); crtc_state =drm_atomic_get_crtc_state (state, crtc); +if (IS_ERR (crtc_state)) +return PTR_ERR (crtc_state); + mode = &crtc_state->mode; dst_x = new_plane_state->crtc_x; dst_y = new_plane_state->crtc_y;
Greg Kroah-Hartman
maintainerPATCH 669/676 drm/sti: avoid potential dereference of error pointers
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Ke <[email protected]>
commit 831214f77037de02afc287eae93ce97f218d8c04 upstream.
The return value of drm_atomic_get_crtc_state() needs to be checked. To avoid use of error pointer 'crtc_state' in case of the failure.
--- drivers/gpu/drm/sti/sti_cursor.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/sti/sti_cursor.c +3 -0
@@ -200,6 +200,9 @@ static int sti_cursor_atomic_check(strucreturn 0 ; crtc_state =drm_atomic_get_crtc_state (state, crtc); +if (IS_ERR (crtc_state)) +return PTR_ERR (crtc_state); + mode = &crtc_state->mode; dst_x = new_plane_state->crtc_x; dst_y = new_plane_state->crtc_y;
Greg Kroah-Hartman
maintainerPATCH 670/676 drm/mediatek: Fix child node refcount handling in early exit
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Carrasco <[email protected]>
commit f708e8b4cfd16e5c8cd8d7fcfcb2fb2c6ed93af3 upstream.
Early exits (goto, break, return) from for_each_child_of_node() required an explicit call to of_node_put(), which was not introduced with the break if cnt == MAX_CRTC.
Add the missing of_node_put() before the break.
--- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/gpu/drm/mediatek/mtk_drm_drv.c +3 -1
@@ -378,8 +378,10 @@ static bool mtk_drm_get_all_drm_priv(strif (all_drm_priv[cnt] && all_drm_priv[cnt]->mtk_drm_bound) cnt++; -if (cnt ==MAX_CRTC ) +if (cnt ==MAX_CRTC ) { +of_node_put (node);break ; + } }if (drm_priv->data->mmsys_dev_num == cnt) {
Greg Kroah-Hartman
maintainerPATCH 671/676 drm/etnaviv: flush shader L1 cache after user commandstream
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lucas Stach <[email protected]>
commit 4f8dbadef085ab447a01a8d4806a3f629fea05ed upstream.
The shader L1 cache is a writeback cache for shader loads/stores and thus must be flushed before any BOs backing the shader buffers are potentially freed.
--- drivers/gpu/drm/etnaviv/etnaviv_buffer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/etnaviv/etnaviv_buffer.c +2 -1
@@ -482,7 +482,8 @@ void etnaviv_buffer_queue(struct etnaviv }else {CMD_LOAD_STATE (buffer,VIVS_GL_FLUSH_CACHE ,VIVS_GL_FLUSH_CACHE_DEPTH | -VIVS_GL_FLUSH_CACHE_COLOR ); +VIVS_GL_FLUSH_CACHE_COLOR | +VIVS_GL_FLUSH_CACHE_SHADER_L1 );if (has_blt) {CMD_LOAD_STATE (buffer,VIVS_BLT_ENABLE ,0x1 );CMD_LOAD_STATE (buffer,VIVS_BLT_SET_COMMAND ,0x1 );
Greg Kroah-Hartman
maintainerPATCH 672/676 drm: xlnx: zynqmp_dpsub: fix hotplug detection
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steffen Dirkwinkel <[email protected]>
commit 71ba1c9b1c717831920c3d432404ee5a707e04b4 upstream.
drm_kms_helper_poll_init needs to be called after zynqmp_dpsub_kms_init. zynqmp_dpsub_kms_init creates the connector and without it we don't enable hotplug detection.
--- drivers/gpu/drm/xlnx/zynqmp_kms.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/xlnx/zynqmp_kms.c +2 -2
@@ -506,12 +506,12 @@ int zynqmp_dpsub_drm_init(struct zynqmp_if (ret)return ret; -drm_kms_helper_poll_init (drm); - ret =zynqmp_dpsub_kms_init (dpsub);if (ret <0 ) goto err_poll_fini; +drm_kms_helper_poll_init (drm); +/* Reset all components and register the DRM device. */ drm_mode_config_reset (drm);
Greg Kroah-Hartman
maintainerPATCH 673/676 drm/amdkfd: Use the correct wptr size
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lijo Lazar <[email protected]>
commit cdc6705f98ea3f854a60ba8c9b19228e197ae384 upstream.
Write pointer could be 32-bit or 64-bit. Use the correct size during initialization.
--- drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c +1 -1
@@ -123,7 +123,7 @@ static bool kq_initialize(struct kernel_memset (kq->pq_kernel_addr,0 , queue_size);memset (kq->rptr_kernel,0 ,sizeof (*kq->rptr_kernel)); -memset (kq->wptr_kernel,0 ,sizeof (*kq->wptr_kernel)); +memset (kq->wptr_kernel,0 , dev->kfd->device_info.doorbell_size); prop.queue_size = queue_size; prop.is_interop = false;