5.15.61-rc1 review
Subsystems (11)
Greg Kroah-Hartman
maintainerPATCH 272/779 media: imx-jpeg: Set V4L2_BUF_FLAG_LAST at eos
In reply to Greg Kroah-HartmanFrom: Ming Qian <[email protected]>
[ Upstream commit d8ebe298d008ccbae3011cbeb139707f01a730c8 ]
The V4L2_EVENT_EOS event is a deprecated behavior, the V4L2_BUF_FLAG_LAST buffer flag should be used instead.
--- drivers/media/platform/imx-jpeg/mxc-jpeg.c | 41 ++++++++++++++++++++-- drivers/media/platform/imx-jpeg/mxc-jpeg.h | 1 + 2 files changed, 40 insertions(+), 2 deletions(-)
drivers/media/platform/imx-jpeg/mxc-jpeg.c +39 -2
@@ -988,6 +988,20 @@ static void mxc_jpeg_device_run(void *priv)spin_unlock_irqrestore (&ctx->mxc_jpeg->hw_lock, flags); } +static void mxc_jpeg_set_last_buffer_dequeued (struct mxc_jpeg_ctx *ctx) +{ +struct vb2_queue *q; + + ctx->stopped =1 ; + q =v4l2_m2m_get_dst_vq (ctx->fh.m2m_ctx); +if (!list_empty (&q->done_list)) +return ; + + q->last_buffer_dequeued = true; +wake_up (&q->done_wq); + ctx->stopped =0 ; +} +static int mxc_jpeg_decoder_cmd (struct file *file,void *priv,struct v4l2_decoder_cmd *cmd) {
@@ -1005,6 +1019,7 @@ static int mxc_jpeg_decoder_cmd(struct file *file, void *priv,if (v4l2_m2m_num_src_bufs_ready (fh->m2m_ctx) ==0 ) {/* No more src bufs, notify app EOS */ notify_eos (ctx); +mxc_jpeg_set_last_buffer_dequeued (ctx); }else {/* will send EOS later*/ ctx->stopping =1 ;
@@ -1031,6 +1046,7 @@ static int mxc_jpeg_encoder_cmd(struct file *file, void *priv,if (v4l2_m2m_num_src_bufs_ready (fh->m2m_ctx) ==0 ) {/* No more src bufs, notify app EOS */ notify_eos (ctx); +mxc_jpeg_set_last_buffer_dequeued (ctx); }else {/* will send EOS later*/ ctx->stopping =1 ;
@@ -1107,6 +1123,10 @@ static void mxc_jpeg_stop_streaming(struct vb2_queue *q)v4l2_m2m_buf_done (vbuf,VB2_BUF_STATE_ERROR ); }pm_runtime_put_sync (&ctx->mxc_jpeg->pdev->dev); +if (V4L2_TYPE_IS_OUTPUT (q->type)) { + ctx->stopping =0 ; + ctx->stopped =0 ; + } } static int mxc_jpeg_valid_comp_id(struct device *dev,
@@ -1398,12 +1418,29 @@ static int mxc_jpeg_buf_prepare(struct vb2_buffer *vb)return 0 ; } +static void mxc_jpeg_buf_finish (struct vb2_buffer *vb) +{ +struct vb2_v4l2_buffer *vbuf =to_vb2_v4l2_buffer (vb); +struct mxc_jpeg_ctx *ctx =vb2_get_drv_priv (vb->vb2_queue); +struct vb2_queue *q = vb->vb2_queue; + +if (V4L2_TYPE_IS_OUTPUT (vb->type)) +return ; +if (!ctx->stopped) +return ; +if (list_empty (&q->done_list)) { + vbuf->flags |=V4L2_BUF_FLAG_LAST ; + ctx->stopped =0 ; + } +} +static const struct vb2_ops mxc_jpeg_qops = { .queue_setup = mxc_jpeg_queue_setup, .wait_prepare = vb2_ops_wait_prepare, .wait_finish = vb2_ops_wait_finish, .buf_out_validate = mxc_jpeg_buf_out_validate, .buf_prepare = mxc_jpeg_buf_prepare, + .buf_finish = mxc_jpeg_buf_finish, .start_streaming = mxc_jpeg_start_streaming, .stop_streaming = mxc_jpeg_stop_streaming, .buf_queue = mxc_jpeg_buf_queue,
@@ -1839,14 +1876,14 @@ static int mxc_jpeg_dqbuf(struct file *file, void *priv,int ret;dev_dbg (dev,"DQBUF type=%d, index=%d" , buf->type, buf->index); -if (ctx->stopping ==1 && num_src_ready ==0 ) { +if (ctx->stopping ==1 && num_src_ready ==0 ) {/* No more src bufs, notify app EOS */ notify_eos (ctx); ctx->stopping =0 ; +mxc_jpeg_set_last_buffer_dequeued (ctx); } ret =v4l2_m2m_dqbuf (file, fh->m2m_ctx, buf); -return ret; }
drivers/media/platform/imx-jpeg/mxc-jpeg.h +1 -0
@@ -91,6 +91,7 @@ struct mxc_jpeg_ctx {struct v4l2_fh fh;enum mxc_jpeg_enc_state enc_state;unsigned int stopping; +unsigned int stopped;unsigned int slot; };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 273/779 media: imx-jpeg: Refactor function mxc_jpeg_parse
In reply to Greg Kroah-HartmanFrom: Ming Qian <[email protected]>
[ Upstream commit 8dd504a3a0a5f73b4c137ce3afc35936a4ecd871 ]
Refine code to support dynamic resolution change
--- drivers/media/platform/imx-jpeg/mxc-jpeg.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
drivers/media/platform/imx-jpeg/mxc-jpeg.c +6 -7
@@ -1236,8 +1236,7 @@ static void mxc_jpeg_sizeimage(struct mxc_jpeg_q_data *q) } } -static int mxc_jpeg_parse (struct mxc_jpeg_ctx *ctx, -u8 *src_addr,u32 size,bool *dht_needed) +static int mxc_jpeg_parse (struct mxc_jpeg_ctx *ctx,struct vb2_buffer *vb) {struct device *dev = ctx->mxc_jpeg->dev;struct mxc_jpeg_q_data *q_data_out, *q_data_cap;
@@ -1247,6 +1246,9 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx,struct v4l2_jpeg_header header;struct mxc_jpeg_sof *psof =NULL ;struct mxc_jpeg_sos *psos =NULL ; +struct mxc_jpeg_src_buf *jpeg_src_buf =vb2_to_mxc_buf (vb); +u8 *src_addr = (u8 *)vb2_plane_vaddr (vb,0 ); +u32 size =vb2_get_plane_payload (vb,0 );int ret;memset (&header,0 ,sizeof (header));
@@ -1257,7 +1259,7 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, }/* if DHT marker present, no need to inject default one */ - *dht_needed = (header.num_dht ==0 ); + jpeg_src_buf->dht_needed = (header.num_dht ==0 ); q_data_out =mxc_jpeg_get_q_data (ctx,V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE );
@@ -1372,10 +1374,7 @@ static void mxc_jpeg_buf_queue(struct vb2_buffer *vb) jpeg_src_buf =vb2_to_mxc_buf (vb); jpeg_src_buf->jpeg_parse_error = false; - ret =mxc_jpeg_parse (ctx, - (u8 *)vb2_plane_vaddr (vb,0 ), -vb2_get_plane_payload (vb,0 ), - &jpeg_src_buf->dht_needed); + ret =mxc_jpeg_parse (ctx, vb);if (ret) jpeg_src_buf->jpeg_parse_error = true;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 274/779 media: imx-jpeg: Identify and handle precision correctly
In reply to Greg Kroah-HartmanFrom: Ming Qian <[email protected]>
[ Upstream commit bec0a3a67389ede106d0661a007edf832878d8b2 ]
The decoder will save the precision that was detected from jpeg header and use it later, when choosing the pixel format and also calculate bytesperline according to precision.
The 12bit jpeg is not supported yet,
but driver shouldn't led to serious problem if user enqueue a 12 bit jpeg. And the 12bit jpeg is supported by hardware, driver may support it later.
[hverkuil: document the new precision field]
--- drivers/media/platform/imx-jpeg/mxc-jpeg.c | 37 +++++++++++++++------- drivers/media/platform/imx-jpeg/mxc-jpeg.h | 2 ++ 2 files changed, 27 insertions(+), 12 deletions(-)
drivers/media/platform/imx-jpeg/mxc-jpeg.c +25 -12
@@ -82,6 +82,7 @@ static const struct mxc_jpeg_fmt mxc_formats[] = { .h_align = 3, .v_align = 3, .flags = MXC_JPEG_FMT_TYPE_RAW, + .precision = 8, }, { .name = "ARGB", /* ARGBARGB packed format */
@@ -93,6 +94,7 @@ static const struct mxc_jpeg_fmt mxc_formats[] = { .h_align = 3, .v_align = 3, .flags = MXC_JPEG_FMT_TYPE_RAW, + .precision = 8, }, { .name = "YUV420", /* 1st plane = Y, 2nd plane = UV */
@@ -104,6 +106,7 @@ static const struct mxc_jpeg_fmt mxc_formats[] = { .h_align = 4, .v_align = 4, .flags = MXC_JPEG_FMT_TYPE_RAW, + .precision = 8, }, { .name = "YUV422", /* YUYV */
@@ -115,6 +118,7 @@ static const struct mxc_jpeg_fmt mxc_formats[] = { .h_align = 4, .v_align = 3, .flags = MXC_JPEG_FMT_TYPE_RAW, + .precision = 8, }, { .name = "YUV444", /* YUVYUV */
@@ -126,6 +130,7 @@ static const struct mxc_jpeg_fmt mxc_formats[] = { .h_align = 3, .v_align = 3, .flags = MXC_JPEG_FMT_TYPE_RAW, + .precision = 8, }, { .name = "Gray", /* Gray (Y8/Y12) or Single Comp */
@@ -137,6 +142,7 @@ static const struct mxc_jpeg_fmt mxc_formats[] = { .h_align = 3, .v_align = 3, .flags = MXC_JPEG_FMT_TYPE_RAW, + .precision = 8, }, };
@@ -1166,14 +1172,17 @@ static u32 mxc_jpeg_get_image_format(struct device *dev,for (i =0 ; i <MXC_JPEG_NUM_FORMATS ; i++)if (mxc_formats[i].subsampling == header->frame.subsampling && - mxc_formats[i].nc == header->frame.num_components) { + mxc_formats[i].nc == header->frame.num_components && + mxc_formats[i].precision == header->frame.precision) { fourcc = mxc_formats[i].fourcc;break ; }if (fourcc ==0 ) { -dev_err (dev,"Could not identify image format nc=%d, subsampling=%d\n" , +dev_err (dev, +"Could not identify image format nc=%d, subsampling=%d, precision=%d\n" , header->frame.num_components, - header->frame.subsampling); + header->frame.subsampling, + header->frame.precision);return fourcc; }/*
@@ -1199,18 +1208,22 @@ static void mxc_jpeg_bytesperline(struct mxc_jpeg_q_data *q,/* bytesperline unused for compressed formats */ q->bytesperline[0 ] =0 ; q->bytesperline[1 ] =0 ; - }else if (q->fmt->fourcc ==V4L2_PIX_FMT_NV12M ) { + }else if (q->fmt->subsampling ==V4L2_JPEG_CHROMA_SUBSAMPLING_420 ) {/* When the image format is planar the bytesperline value * applies to the first plane and is divided by the same factor * as the width field for the other planes */ - q->bytesperline[0 ] = q->w * (precision /8 ) * - (q->fmt->depth /8 ); + q->bytesperline[0 ] = q->w *DIV_ROUND_UP (precision,8 ); q->bytesperline[1 ] = q->bytesperline[0 ]; + }else if (q->fmt->subsampling ==V4L2_JPEG_CHROMA_SUBSAMPLING_422 ) { + q->bytesperline[0 ] = q->w *DIV_ROUND_UP (precision,8 ) *2 ; + q->bytesperline[1 ] =0 ; + }else if (q->fmt->subsampling ==V4L2_JPEG_CHROMA_SUBSAMPLING_444 ) { + q->bytesperline[0 ] = q->w *DIV_ROUND_UP (precision,8 ) * q->fmt->nc; + q->bytesperline[1 ] =0 ; }else { -/* single plane formats */ - q->bytesperline[0 ] = q->w * (precision /8 ) * - (q->fmt->depth /8 ); +/* grayscale */ + q->bytesperline[0 ] = q->w *DIV_ROUND_UP (precision,8 ); q->bytesperline[1 ] =0 ; } }
@@ -1344,7 +1357,7 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb) (fourcc >> 24) & 0xff);/* setup bytesperline/sizeimage for capture queue */ -mxc_jpeg_bytesperline (q_data_cap, header.frame.precision); +mxc_jpeg_bytesperline (q_data_cap, q_data_cap->fmt->precision);mxc_jpeg_sizeimage (q_data_cap);/*
@@ -1500,7 +1513,7 @@ static void mxc_jpeg_set_default_params(struct mxc_jpeg_ctx *ctx) q[i]->h =MXC_JPEG_DEFAULT_HEIGHT ; q[i]->w_adjusted =MXC_JPEG_DEFAULT_WIDTH ; q[i]->h_adjusted =MXC_JPEG_DEFAULT_HEIGHT ; -mxc_jpeg_bytesperline (q[i],8 ); +mxc_jpeg_bytesperline (q[i], q[i]->fmt->precision);mxc_jpeg_sizeimage (q[i]); } }
@@ -1642,7 +1655,7 @@ static int mxc_jpeg_try_fmt(struct v4l2_format *f, const struct mxc_jpeg_fmt *fm }/* calculate bytesperline & sizeimage into the tmp_q */ -mxc_jpeg_bytesperline (&tmp_q,8 ); +mxc_jpeg_bytesperline (&tmp_q, fmt->precision);mxc_jpeg_sizeimage (&tmp_q);/* adjust user format according to our calculations */
drivers/media/platform/imx-jpeg/mxc-jpeg.h +2 -0
@@ -49,6 +49,7 @@ enum mxc_jpeg_mode {* @h_align: horizontal alignment order (align to 2^h_align) * @v_align: vertical alignment order (align to 2^v_align) * @flags: flags describing format applicability +* @precision: jpeg sample precision */ struct mxc_jpeg_fmt {const char *name;
@@ -60,6 +61,7 @@ struct mxc_jpeg_fmt {int h_align;int v_align;u32 flags; +u8 precision; };struct mxc_jpeg_desc {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 275/779 media: imx-jpeg: Handle source change in a function
In reply to Greg Kroah-HartmanFrom: Ming Qian <[email protected]>
[ Upstream commit 831f87424dd3973612782983ef7352789795b4df ]
Refine code to support dynamic resolution change
--- drivers/media/platform/imx-jpeg/mxc-jpeg.c | 114 ++++++++++++--------- 1 file changed, 65 insertions(+), 49 deletions(-)
drivers/media/platform/imx-jpeg/mxc-jpeg.c +65 -49
@@ -301,6 +301,9 @@ struct mxc_jpeg_src_buf {/* mxc-jpeg specific */ bool dht_needed;bool jpeg_parse_error; +const struct mxc_jpeg_fmt *fmt; +int w; +int h; };static inline struct mxc_jpeg_src_buf *vb2_to_mxc_buf (struct vb2_buffer *vb)
@@ -313,6 +316,9 @@ static unsigned int debug;module_param (debug, int,0644 );MODULE_PARM_DESC (debug,"Debug level (0-3)" ); +static void mxc_jpeg_bytesperline (struct mxc_jpeg_q_data *q,u32 precision); +static void mxc_jpeg_sizeimage (struct mxc_jpeg_q_data *q); +static void _bswap16 (u16 *a) { *a = ((*a &0x00FF ) <<8 ) | ((*a &0xFF00 ) >>8 );
@@ -908,6 +914,59 @@ static void mxc_jpeg_config_enc_desc(struct vb2_buffer *out_buf,mxc_jpeg_set_desc (cfg_desc_handle, reg, slot); } +static bool mxc_jpeg_source_change (struct mxc_jpeg_ctx *ctx, +struct mxc_jpeg_src_buf *jpeg_src_buf) +{ +struct device *dev = ctx->mxc_jpeg->dev; +struct mxc_jpeg_q_data *q_data_cap; +bool src_chg = false; + +if (!jpeg_src_buf->fmt) +return src_chg; + + q_data_cap =mxc_jpeg_get_q_data (ctx,V4L2_BUF_TYPE_VIDEO_CAPTURE ); +if (q_data_cap->w != jpeg_src_buf->w || q_data_cap->h != jpeg_src_buf->h) { +dev_dbg (dev,"Detected jpeg res=(%dx%d)->(%dx%d), pixfmt=%c%c%c%c\n" , + q_data_cap->w, q_data_cap->h, + jpeg_src_buf->w, jpeg_src_buf->h, + (jpeg_src_buf->fmt->fourcc &0xff ), + (jpeg_src_buf->fmt->fourcc >>8 ) &0xff , + (jpeg_src_buf->fmt->fourcc >>16 ) &0xff , + (jpeg_src_buf->fmt->fourcc >>24 ) &0xff ); + +/* +* set-up the capture queue with the pixelformat and resolution +* detected from the jpeg output stream +*/ + q_data_cap->w = jpeg_src_buf->w; + q_data_cap->h = jpeg_src_buf->h; + q_data_cap->fmt = jpeg_src_buf->fmt; + q_data_cap->w_adjusted = q_data_cap->w; + q_data_cap->h_adjusted = q_data_cap->h; + +/* +* align up the resolution for CAST IP, +* but leave the buffer resolution unchanged +*/ +v4l_bound_align_image (&q_data_cap->w_adjusted, + q_data_cap->w_adjusted,/* adjust up */ +MXC_JPEG_MAX_WIDTH , + q_data_cap->fmt->h_align, + &q_data_cap->h_adjusted, + q_data_cap->h_adjusted,/* adjust up */ +MXC_JPEG_MAX_HEIGHT , + q_data_cap->fmt->v_align, +0 ); + +/* setup bytesperline/sizeimage for capture queue */ +mxc_jpeg_bytesperline (q_data_cap, jpeg_src_buf->fmt->precision); +mxc_jpeg_sizeimage (q_data_cap); +notify_src_chg (ctx); + src_chg = true; + } +return src_chg; +} +static void mxc_jpeg_device_run (void *priv) {struct mxc_jpeg_ctx *ctx = priv;
@@ -1200,8 +1259,7 @@ static u32 mxc_jpeg_get_image_format(struct device *dev,return fourcc; } -static void mxc_jpeg_bytesperline (struct mxc_jpeg_q_data *q, -u32 precision) +static void mxc_jpeg_bytesperline (struct mxc_jpeg_q_data *q,u32 precision) {/* Bytes distance between the leftmost pixels in two adjacent lines */ if (q->fmt->fourcc ==V4L2_PIX_FMT_JPEG ) {
@@ -1252,9 +1310,7 @@ static void mxc_jpeg_sizeimage(struct mxc_jpeg_q_data *q)static int mxc_jpeg_parse (struct mxc_jpeg_ctx *ctx,struct vb2_buffer *vb) {struct device *dev = ctx->mxc_jpeg->dev; -struct mxc_jpeg_q_data *q_data_out, *q_data_cap; -enum v4l2_buf_type cap_type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ; -bool src_chg = false; +struct mxc_jpeg_q_data *q_data_out;u32 fourcc;struct v4l2_jpeg_header header;struct mxc_jpeg_sof *psof =NULL ;
@@ -1322,51 +1378,11 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb)if (fourcc ==0 )return -EINVAL ; -/* -* set-up the capture queue with the pixelformat and resolution -* detected from the jpeg output stream -*/ - q_data_cap =mxc_jpeg_get_q_data (ctx, cap_type); -if (q_data_cap->w != header.frame.width || - q_data_cap->h != header.frame.height) - src_chg = true; - q_data_cap->w = header.frame.width; - q_data_cap->h = header.frame.height; - q_data_cap->fmt =mxc_jpeg_find_format (ctx, fourcc); - q_data_cap->w_adjusted = q_data_cap->w; - q_data_cap->h_adjusted = q_data_cap->h; -/* -* align up the resolution for CAST IP, -* but leave the buffer resolution unchanged -*/ -v4l_bound_align_image (&q_data_cap->w_adjusted, - q_data_cap->w_adjusted,/* adjust up */ -MXC_JPEG_MAX_WIDTH , - q_data_cap->fmt->h_align, - &q_data_cap->h_adjusted, - q_data_cap->h_adjusted,/* adjust up */ -MXC_JPEG_MAX_HEIGHT , - q_data_cap->fmt->v_align, -0 ); -dev_dbg (dev,"Detected jpeg res=(%dx%d)->(%dx%d), pixfmt=%c%c%c%c\n" , - q_data_cap->w, q_data_cap->h, - q_data_cap->w_adjusted, q_data_cap->h_adjusted, - (fourcc &0xff ), - (fourcc >>8 ) &0xff , - (fourcc >>16 ) &0xff , - (fourcc >>24 ) &0xff ); - -/* setup bytesperline/sizeimage for capture queue */ -mxc_jpeg_bytesperline (q_data_cap, q_data_cap->fmt->precision); -mxc_jpeg_sizeimage (q_data_cap); + jpeg_src_buf->fmt =mxc_jpeg_find_format (ctx, fourcc); + jpeg_src_buf->w = header.frame.width; + jpeg_src_buf->h = header.frame.height; -/* -* if the CAPTURE format was updated with new values, regardless of -* whether they match the values set by the client or not, signal -* a source change event -*/ -if (src_chg) -notify_src_chg (ctx); +mxc_jpeg_source_change (ctx, jpeg_src_buf);return 0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 276/779 media: imx-jpeg: Support dynamic resolution change
In reply to Greg Kroah-HartmanFrom: Ming Qian <[email protected]>
[ Upstream commit b4e1fb8643daabba850e97df532191acffc23e6a ]
To support dynamic resolution change,
driver should meet the following conditions:
1. the previous pictures are all decoded before source change event.
2. prevent decoding new resolution pictures with incorrect capture buffer, until user handle source change event and setup capture.
3. report correct fmt and resolution during source change.
--- drivers/media/platform/imx-jpeg/mxc-jpeg.c | 69 +++++++++++++++++----- drivers/media/platform/imx-jpeg/mxc-jpeg.h | 2 + 2 files changed, 55 insertions(+), 16 deletions(-)
drivers/media/platform/imx-jpeg/mxc-jpeg.c +53 -16
@@ -919,13 +919,14 @@ static bool mxc_jpeg_source_change(struct mxc_jpeg_ctx *ctx, {struct device *dev = ctx->mxc_jpeg->dev;struct mxc_jpeg_q_data *q_data_cap; -bool src_chg = false;if (!jpeg_src_buf->fmt) -return src_chg; +return false; q_data_cap =mxc_jpeg_get_q_data (ctx,V4L2_BUF_TYPE_VIDEO_CAPTURE ); -if (q_data_cap->w != jpeg_src_buf->w || q_data_cap->h != jpeg_src_buf->h) { +if (q_data_cap->fmt != jpeg_src_buf->fmt || + q_data_cap->w != jpeg_src_buf->w || + q_data_cap->h != jpeg_src_buf->h) { dev_dbg(dev, "Detected jpeg res=(%dx%d)->(%dx%d), pixfmt=%c%c%c%c\n", q_data_cap->w, q_data_cap->h, jpeg_src_buf->w, jpeg_src_buf->h,
@@ -962,9 +963,16 @@ static bool mxc_jpeg_source_change(struct mxc_jpeg_ctx *ctx,mxc_jpeg_bytesperline (q_data_cap, jpeg_src_buf->fmt->precision);mxc_jpeg_sizeimage (q_data_cap);notify_src_chg (ctx); - src_chg = true; + ctx->source_change =1 ; } -return src_chg; +return ctx->source_change ? true : false; +} + +static int mxc_jpeg_job_ready (void *priv) +{ +struct mxc_jpeg_ctx *ctx = priv; + +return ctx->source_change ?0 :1 ; }static void mxc_jpeg_device_run (void *priv)
@@ -1014,6 +1022,13 @@ static void mxc_jpeg_device_run(void *priv)return ; } +if (ctx->mxc_jpeg->mode ==MXC_JPEG_DECODE ) { +if (ctx->source_change ||mxc_jpeg_source_change (ctx, jpeg_src_buf)) { +spin_unlock_irqrestore (&ctx->mxc_jpeg->hw_lock, flags); +v4l2_m2m_job_finish (jpeg->m2m_dev, ctx->fh.m2m_ctx); +return ; + } + }/* * TODO: this reset should be removed, once we figure out
@@ -1065,6 +1080,7 @@ static void mxc_jpeg_set_last_buffer_dequeued(struct mxc_jpeg_ctx *ctx) q->last_buffer_dequeued = true;wake_up (&q->done_wq); ctx->stopped =0 ; + ctx->header_parsed = false; } static int mxc_jpeg_decoder_cmd(struct file *file, void *priv,
@@ -1158,6 +1174,8 @@ static int mxc_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)struct mxc_jpeg_q_data *q_data =mxc_jpeg_get_q_data (ctx, q->type);int ret; +if (ctx->mxc_jpeg->mode ==MXC_JPEG_DECODE &&V4L2_TYPE_IS_CAPTURE (q->type)) + ctx->source_change =0 ;dev_dbg (ctx->mxc_jpeg->dev,"Start streaming ctx=%p" , ctx); q_data->sequence =0 ;
@@ -1336,16 +1354,15 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb)dev_warn (dev,"Invalid user resolution 0x0" );dev_warn (dev,"Keeping resolution from JPEG: %dx%d" , header.frame.width, header.frame.height); - q_data_out->w = header.frame.width; - q_data_out->h = header.frame.height; }else if (header.frame.width != q_data_out->w || header.frame.height != q_data_out->h) {dev_err (dev,"Resolution mismatch: %dx%d (JPEG) versus %dx%d(user)" , header.frame.width, header.frame.height, q_data_out->w, q_data_out->h); -return -EINVAL ; } + q_data_out->w = header.frame.width; + q_data_out->h = header.frame.height;if (header.frame.width %8 !=0 || header.frame.height %8 !=0 ) {dev_err (dev,"JPEG width or height not multiple of 8: %dx%d\n" , header.frame.width, header.frame.height);
@@ -1381,8 +1398,10 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb) jpeg_src_buf->fmt =mxc_jpeg_find_format (ctx, fourcc); jpeg_src_buf->w = header.frame.width; jpeg_src_buf->h = header.frame.height; + ctx->header_parsed = true; -mxc_jpeg_source_change (ctx, jpeg_src_buf); +if (!v4l2_m2m_num_src_bufs_ready (ctx->fh.m2m_ctx)) +mxc_jpeg_source_change (ctx, jpeg_src_buf);return 0 ; }
@@ -1459,6 +1478,7 @@ static void mxc_jpeg_buf_finish(struct vb2_buffer *vb)if (list_empty (&q->done_list)) { vbuf->flags |=V4L2_BUF_FLAG_LAST ; ctx->stopped =0 ; + ctx->header_parsed = false; } }
@@ -1604,26 +1624,42 @@ static int mxc_jpeg_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) {struct mxc_jpeg_ctx *ctx =mxc_jpeg_fh_to_ctx (priv); +struct mxc_jpeg_q_data *q_data =mxc_jpeg_get_q_data (ctx, f->type); -if (ctx->mxc_jpeg->mode ==MXC_JPEG_ENCODE ) +if (ctx->mxc_jpeg->mode ==MXC_JPEG_ENCODE ) {return enum_fmt (mxc_formats,MXC_JPEG_NUM_FORMATS , f,MXC_JPEG_FMT_TYPE_ENC ); -else + }else if (!ctx->header_parsed) {return enum_fmt (mxc_formats,MXC_JPEG_NUM_FORMATS , f,MXC_JPEG_FMT_TYPE_RAW ); + }else { +/* For the decoder CAPTURE queue, only enumerate the raw formats +* supported for the format currently active on OUTPUT +* (more precisely what was propagated on capture queue +* after jpeg parse on the output buffer) +*/ +if (f->index) +return -EINVAL ; + f->pixelformat = q_data->fmt->fourcc; +strscpy (f->description, q_data->fmt->name,sizeof (f->description)); +return 0 ; + } }static int mxc_jpeg_enum_fmt_vid_out (struct file *file,void *priv,struct v4l2_fmtdesc *f) {struct mxc_jpeg_ctx *ctx =mxc_jpeg_fh_to_ctx (priv); +u32 type = ctx->mxc_jpeg->mode ==MXC_JPEG_DECODE ?MXC_JPEG_FMT_TYPE_ENC : +MXC_JPEG_FMT_TYPE_RAW ; +int ret; + ret =enum_fmt (mxc_formats,MXC_JPEG_NUM_FORMATS , f, type); +if (ret) +return ret;if (ctx->mxc_jpeg->mode ==MXC_JPEG_DECODE ) -return enum_fmt (mxc_formats,MXC_JPEG_NUM_FORMATS , f, -MXC_JPEG_FMT_TYPE_ENC ); -else -return enum_fmt (mxc_formats,MXC_JPEG_NUM_FORMATS , f, -MXC_JPEG_FMT_TYPE_RAW ); + f->flags =V4L2_FMT_FLAG_DYN_RESOLUTION ; +return 0 ; } static int mxc_jpeg_try_fmt(struct v4l2_format *f, const struct mxc_jpeg_fmt *fmt,
@@ -1981,6 +2017,7 @@ static const struct v4l2_file_operations mxc_jpeg_fops = { };static const struct v4l2_m2m_ops mxc_jpeg_m2m_ops = { + .job_ready = mxc_jpeg_job_ready, .device_run = mxc_jpeg_device_run, };
drivers/media/platform/imx-jpeg/mxc-jpeg.h +2 -0
@@ -95,6 +95,8 @@ struct mxc_jpeg_ctx {unsigned int stopping;unsigned int stopped;unsigned int slot; +unsigned int source_change; +bool header_parsed; };struct mxc_jpeg_slot_data {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 277/779 media: imx-jpeg: Align upwards buffer size
In reply to Greg Kroah-HartmanFrom: Ming Qian <[email protected]>
[ Upstream commit 9e7aa76cdb02923ee23a0ddd48f38bdc3512f92b ]
The hardware can support any image size WxH,
with arbitrary W (image width) and H (image height) dimensions.
Align upwards buffer size for both encoder and decoder. and leave the picture resolution unchanged.
For decoder, the risk of memory out of bounds can be avoided. For both encoder and decoder, the driver will lift the limitation of resolution alignment.
For example, the decoder can support jpeg whose resolution is 227x149 the encoder can support nv12 1080P, won't change it to 1920x1072.
--- drivers/media/platform/imx-jpeg/mxc-jpeg.c | 88 +++++++++------------- 1 file changed, 37 insertions(+), 51 deletions(-)
drivers/media/platform/imx-jpeg/mxc-jpeg.c +37 -51
@@ -875,8 +875,8 @@ static void mxc_jpeg_config_enc_desc(struct vb2_buffer *out_buf, jpeg->slot_data[slot].cfg_stream_size =mxc_jpeg_setup_cfg_stream (cfg_stream_vaddr, q_data->fmt->fourcc, - q_data->w_adjusted, - q_data->h_adjusted); + q_data->w, + q_data->h);/* chain the config descriptor with the encoding descriptor */ cfg_desc->next_descpt_ptr = desc_handle |MXC_NXT_DESCPT_EN ;
@@ -956,7 +956,7 @@ static bool mxc_jpeg_source_change(struct mxc_jpeg_ctx *ctx, &q_data_cap->h_adjusted, q_data_cap->h_adjusted,/* adjust up */ MXC_JPEG_MAX_HEIGHT , - q_data_cap->fmt->v_align, +0 , 0);/* setup bytesperline/sizeimage for capture queue */
@@ -1145,16 +1145,28 @@ static int mxc_jpeg_queue_setup(struct vb2_queue *q, {struct mxc_jpeg_ctx *ctx =vb2_get_drv_priv (q);struct mxc_jpeg_q_data *q_data =NULL ; +struct mxc_jpeg_q_data tmp_q;int i; q_data =mxc_jpeg_get_q_data (ctx, q->type);if (!q_data)return -EINVAL ; + tmp_q.fmt = q_data->fmt; + tmp_q.w = q_data->w_adjusted; + tmp_q.h = q_data->h_adjusted; +for (i =0 ; i <MXC_JPEG_MAX_PLANES ; i++) { + tmp_q.bytesperline[i] = q_data->bytesperline[i]; + tmp_q.sizeimage[i] = q_data->sizeimage[i]; + } +mxc_jpeg_sizeimage (&tmp_q); +for (i =0 ; i <MXC_JPEG_MAX_PLANES ; i++) + tmp_q.sizeimage[i] =max (tmp_q.sizeimage[i], q_data->sizeimage[i]); +/* Handle CREATE_BUFS situation - *nplanes != 0 */ if (*nplanes) {for (i =0 ; i < *nplanes; i++) { -if (sizes[i] < q_data->sizeimage[i]) +if (sizes[i] < tmp_q.sizeimage[i])return -EINVAL ; }return 0 ;
@@ -1163,7 +1175,7 @@ static int mxc_jpeg_queue_setup(struct vb2_queue *q,/* Handle REQBUFS situation */ *nplanes = q_data->fmt->colplanes;for (i =0 ; i < *nplanes; i++) - sizes[i] = q_data->sizeimage[i]; + sizes[i] = tmp_q.sizeimage[i];return 0 ; }
@@ -1363,11 +1375,6 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb) } q_data_out->w = header.frame.width; q_data_out->h = header.frame.height; -if (header.frame.width %8 !=0 || header.frame.height %8 !=0 ) { -dev_err (dev,"JPEG width or height not multiple of 8: %dx%d\n" , - header.frame.width, header.frame.height); -return -EINVAL ; - }if (header.frame.width >MXC_JPEG_MAX_WIDTH || header.frame.height >MXC_JPEG_MAX_HEIGHT ) { dev_err(dev, "JPEG width or height should be <= 8192: %dx%d\n",
@@ -1679,22 +1686,17 @@ static int mxc_jpeg_try_fmt(struct v4l2_format *f, const struct mxc_jpeg_fmt *fm pix_mp->num_planes = fmt->colplanes; pix_mp->pixelformat = fmt->fourcc; -/* -* use MXC_JPEG_H_ALIGN instead of fmt->v_align, for vertical -* alignment, to loosen up the alignment to multiple of 8, -* otherwise NV12-1080p fails as 1080 is not a multiple of 16 -*/ + pix_mp->width = w; + pix_mp->height = h;v4l_bound_align_image (&w, -MXC_JPEG_MIN_WIDTH , - w,/* adjust downwards*/ + w,/* adjust upwards*/ +MXC_JPEG_MAX_WIDTH , fmt->h_align, &h, -MXC_JPEG_MIN_HEIGHT , - h,/* adjust downwards*/ -MXC_JPEG_H_ALIGN , + h,/* adjust upwards*/ +MXC_JPEG_MAX_HEIGHT , +0 ,0 ); - pix_mp->width = w;/* negotiate the width */ - pix_mp->height = h;/* negotiate the height */ /* get user input into the tmp_q */ tmp_q.w = w;
@@ -1820,35 +1822,19 @@ static int mxc_jpeg_s_fmt(struct mxc_jpeg_ctx *ctx, q_data->w_adjusted = q_data->w; q_data->h_adjusted = q_data->h; -if (jpeg->mode ==MXC_JPEG_DECODE ) { -/* -* align up the resolution for CAST IP, -* but leave the buffer resolution unchanged -*/ -v4l_bound_align_image (&q_data->w_adjusted, - q_data->w_adjusted,/* adjust upwards */ -MXC_JPEG_MAX_WIDTH , - q_data->fmt->h_align, - &q_data->h_adjusted, - q_data->h_adjusted,/* adjust upwards */ -MXC_JPEG_MAX_HEIGHT , - q_data->fmt->v_align, -0 ); - }else { -/* -* align down the resolution for CAST IP, -* but leave the buffer resolution unchanged -*/ -v4l_bound_align_image (&q_data->w_adjusted, -MXC_JPEG_MIN_WIDTH , - q_data->w_adjusted,/* adjust downwards*/ - q_data->fmt->h_align, - &q_data->h_adjusted, -MXC_JPEG_MIN_HEIGHT , - q_data->h_adjusted,/* adjust downwards*/ - q_data->fmt->v_align, -0 ); - } +/* +* align up the resolution for CAST IP, +* but leave the buffer resolution unchanged +*/ +v4l_bound_align_image (&q_data->w_adjusted, + q_data->w_adjusted,/* adjust upwards */ +MXC_JPEG_MAX_WIDTH , + q_data->fmt->h_align, + &q_data->h_adjusted, + q_data->h_adjusted,/* adjust upwards */ +MXC_JPEG_MAX_HEIGHT , + q_data->fmt->v_align, +0 );for (i =0 ; i < pix_mp->num_planes; i++) { q_data->bytesperline[i] = pix_mp->plane_fmt[i].bytesperline;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 278/779 media: imx-jpeg: Implement drain using v4l2-mem2mem helpers
In reply to Greg Kroah-HartmanFrom: Ming Qian <[email protected]>
[ Upstream commit 4911c5acf9351c4caf692895c7cf6a4fa46c26b0 ]
v4l2 m2m has supplied some helper function to handle drain, so the driver can use the helper function directly.
--- drivers/media/platform/imx-jpeg/mxc-jpeg.c | 155 ++++++++++----------- drivers/media/platform/imx-jpeg/mxc-jpeg.h | 2 - 2 files changed, 73 insertions(+), 84 deletions(-)
drivers/media/platform/imx-jpeg/mxc-jpeg.c +73 -82
@@ -545,6 +545,18 @@ static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg, jpeg->slot_data[slot].used = false; } +static void mxc_jpeg_check_and_set_last_buffer (struct mxc_jpeg_ctx *ctx, +struct vb2_v4l2_buffer *src_buf, +struct vb2_v4l2_buffer *dst_buf) +{ +if (v4l2_m2m_is_last_draining_src_buf (ctx->fh.m2m_ctx, src_buf)) { + dst_buf->flags |=V4L2_BUF_FLAG_LAST ; +v4l2_m2m_mark_stopped (ctx->fh.m2m_ctx); +notify_eos (ctx); + ctx->header_parsed = false; + } +} +static irqreturn_t mxc_jpeg_dec_irq (int irq,void *priv) {struct mxc_jpeg_dev *jpeg = priv;
@@ -619,6 +631,7 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)dev_dbg (dev,"Decoder DHT cfg finished. Start decoding...\n" ); goto job_unlock; } +if (jpeg->mode ==MXC_JPEG_ENCODE ) { payload =readl (reg +MXC_SLOT_OFFSET (slot,SLOT_BUF_PTR ));vb2_set_plane_payload (&dst_buf->vb2_buf,0 , payload);
@@ -647,6 +660,7 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv) buffers_done: jpeg->slot_data[slot].used = false;/* unused, but don't free */ +mxc_jpeg_check_and_set_last_buffer (ctx, src_buf, dst_buf);v4l2_m2m_src_buf_remove (ctx->fh.m2m_ctx);v4l2_m2m_dst_buf_remove (ctx->fh.m2m_ctx);v4l2_m2m_buf_done (src_buf, buf_state);
@@ -1013,6 +1027,7 @@ static void mxc_jpeg_device_run(void *priv) jpeg_src_buf->jpeg_parse_error = true; }if (jpeg_src_buf->jpeg_parse_error) { +mxc_jpeg_check_and_set_last_buffer (ctx, src_buf, dst_buf);v4l2_m2m_src_buf_remove (ctx->fh.m2m_ctx);v4l2_m2m_dst_buf_remove (ctx->fh.m2m_ctx);v4l2_m2m_buf_done (src_buf,VB2_BUF_STATE_ERROR );
@@ -1068,45 +1083,33 @@ static void mxc_jpeg_device_run(void *priv)spin_unlock_irqrestore (&ctx->mxc_jpeg->hw_lock, flags); } -static void mxc_jpeg_set_last_buffer_dequeued (struct mxc_jpeg_ctx *ctx) -{ -struct vb2_queue *q; - - ctx->stopped =1 ; - q =v4l2_m2m_get_dst_vq (ctx->fh.m2m_ctx); -if (!list_empty (&q->done_list)) -return ; - - q->last_buffer_dequeued = true; -wake_up (&q->done_wq); - ctx->stopped =0 ; - ctx->header_parsed = false; -} -static int mxc_jpeg_decoder_cmd (struct file *file,void *priv,struct v4l2_decoder_cmd *cmd) {struct v4l2_fh *fh = file->private_data;struct mxc_jpeg_ctx *ctx =mxc_jpeg_fh_to_ctx (fh); -struct device *dev = ctx->mxc_jpeg->dev;int ret; ret =v4l2_m2m_ioctl_try_decoder_cmd (file, fh, cmd);if (ret <0 )return ret; -if (cmd->cmd ==V4L2_DEC_CMD_STOP ) { -dev_dbg (dev,"Received V4L2_DEC_CMD_STOP" ); -if (v4l2_m2m_num_src_bufs_ready (fh->m2m_ctx) ==0 ) { -/* No more src bufs, notify app EOS */ -notify_eos (ctx); -mxc_jpeg_set_last_buffer_dequeued (ctx); - }else { -/* will send EOS later*/ - ctx->stopping =1 ; - } +if (!vb2_is_streaming (v4l2_m2m_get_src_vq (fh->m2m_ctx))) +return 0 ; + + ret =v4l2_m2m_ioctl_decoder_cmd (file, priv, cmd); +if (ret <0 ) +return ret; + +if (cmd->cmd ==V4L2_DEC_CMD_STOP && +v4l2_m2m_has_stopped (fh->m2m_ctx)) { +notify_eos (ctx); + ctx->header_parsed = false; } +if (cmd->cmd ==V4L2_DEC_CMD_START && +v4l2_m2m_has_stopped (fh->m2m_ctx)) +vb2_clear_last_buffer_dequeued (&fh->m2m_ctx->cap_q_ctx.q);return 0 ; }
@@ -1115,24 +1118,27 @@ static int mxc_jpeg_encoder_cmd(struct file *file, void *priv, {struct v4l2_fh *fh = file->private_data;struct mxc_jpeg_ctx *ctx =mxc_jpeg_fh_to_ctx (fh); -struct device *dev = ctx->mxc_jpeg->dev;int ret; ret =v4l2_m2m_ioctl_try_encoder_cmd (file, fh, cmd);if (ret <0 )return ret; -if (cmd->cmd ==V4L2_ENC_CMD_STOP ) { -dev_dbg (dev,"Received V4L2_ENC_CMD_STOP" ); -if (v4l2_m2m_num_src_bufs_ready (fh->m2m_ctx) ==0 ) { -/* No more src bufs, notify app EOS */ -notify_eos (ctx); -mxc_jpeg_set_last_buffer_dequeued (ctx); - }else { -/* will send EOS later*/ - ctx->stopping =1 ; - } - } +if (!vb2_is_streaming (v4l2_m2m_get_src_vq (fh->m2m_ctx)) || + !vb2_is_streaming (v4l2_m2m_get_dst_vq (fh->m2m_ctx))) +return 0 ; + + ret =v4l2_m2m_ioctl_encoder_cmd (file, fh, cmd); +if (ret <0 ) +return 0 ; + +if (cmd->cmd ==V4L2_ENC_CMD_STOP && +v4l2_m2m_has_stopped (fh->m2m_ctx)) +notify_eos (ctx); + +if (cmd->cmd ==V4L2_ENC_CMD_START && +v4l2_m2m_has_stopped (fh->m2m_ctx)) +vb2_clear_last_buffer_dequeued (&fh->m2m_ctx->cap_q_ctx.q);return 0 ; }
@@ -1186,6 +1192,8 @@ static int mxc_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)struct mxc_jpeg_q_data *q_data =mxc_jpeg_get_q_data (ctx, q->type);int ret; +v4l2_m2m_update_start_streaming_state (ctx->fh.m2m_ctx, q); +if (ctx->mxc_jpeg->mode ==MXC_JPEG_DECODE &&V4L2_TYPE_IS_CAPTURE (q->type)) ctx->source_change =0 ;dev_dbg (ctx->mxc_jpeg->dev,"Start streaming ctx=%p" , ctx);
@@ -1217,11 +1225,15 @@ static void mxc_jpeg_stop_streaming(struct vb2_queue *q)break ;v4l2_m2m_buf_done (vbuf,VB2_BUF_STATE_ERROR ); } -pm_runtime_put_sync (&ctx->mxc_jpeg->pdev->dev); -if (V4L2_TYPE_IS_OUTPUT (q->type)) { - ctx->stopping =0 ; - ctx->stopped =0 ; + +v4l2_m2m_update_stop_streaming_state (ctx->fh.m2m_ctx, q); +if (V4L2_TYPE_IS_OUTPUT (q->type) && +v4l2_m2m_has_stopped (ctx->fh.m2m_ctx)) { +notify_eos (ctx); + ctx->header_parsed = false; } + +pm_runtime_put_sync (&ctx->mxc_jpeg->pdev->dev); } static int mxc_jpeg_valid_comp_id(struct device *dev,
@@ -1420,6 +1432,20 @@ static void mxc_jpeg_buf_queue(struct vb2_buffer *vb)struct mxc_jpeg_ctx *ctx =vb2_get_drv_priv (vb->vb2_queue);struct mxc_jpeg_src_buf *jpeg_src_buf; +if (V4L2_TYPE_IS_CAPTURE (vb->vb2_queue->type) && +vb2_is_streaming (vb->vb2_queue) && +v4l2_m2m_dst_buf_is_last (ctx->fh.m2m_ctx)) { +struct mxc_jpeg_q_data *q_data; + + q_data =mxc_jpeg_get_q_data (ctx, vb->vb2_queue->type); + vbuf->field =V4L2_FIELD_NONE ; + vbuf->sequence = q_data->sequence++; +v4l2_m2m_last_buffer_done (ctx->fh.m2m_ctx, vbuf); +notify_eos (ctx); + ctx->header_parsed = false; +return ; + } +if (vb->vb2_queue->type ==V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ) goto end;
@@ -1469,24 +1495,11 @@ static int mxc_jpeg_buf_prepare(struct vb2_buffer *vb) }vb2_set_plane_payload (vb, i, sizeimage); } -return 0 ; -} - -static void mxc_jpeg_buf_finish (struct vb2_buffer *vb) -{ -struct vb2_v4l2_buffer *vbuf =to_vb2_v4l2_buffer (vb); -struct mxc_jpeg_ctx *ctx =vb2_get_drv_priv (vb->vb2_queue); -struct vb2_queue *q = vb->vb2_queue; - -if (V4L2_TYPE_IS_OUTPUT (vb->type)) -return ; -if (!ctx->stopped) -return ; -if (list_empty (&q->done_list)) { - vbuf->flags |=V4L2_BUF_FLAG_LAST ; - ctx->stopped =0 ; - ctx->header_parsed = false; +if (V4L2_TYPE_IS_CAPTURE (vb->vb2_queue->type)) { +vb2_set_plane_payload (vb,0 ,0 ); +vb2_set_plane_payload (vb,1 ,0 ); } +return 0 ; }static const struct vb2_ops mxc_jpeg_qops = {
@@ -1495,7 +1508,6 @@ static const struct vb2_ops mxc_jpeg_qops = { .wait_finish = vb2_ops_wait_finish, .buf_out_validate = mxc_jpeg_buf_out_validate, .buf_prepare = mxc_jpeg_buf_prepare, - .buf_finish = mxc_jpeg_buf_finish, .start_streaming = mxc_jpeg_start_streaming, .stop_streaming = mxc_jpeg_stop_streaming, .buf_queue = mxc_jpeg_buf_queue,
@@ -1916,27 +1928,6 @@ static int mxc_jpeg_subscribe_event(struct v4l2_fh *fh, } } -static int mxc_jpeg_dqbuf (struct file *file,void *priv, -struct v4l2_buffer *buf) -{ -struct v4l2_fh *fh = file->private_data; -struct mxc_jpeg_ctx *ctx =mxc_jpeg_fh_to_ctx (priv); -struct device *dev = ctx->mxc_jpeg->dev; -int num_src_ready =v4l2_m2m_num_src_bufs_ready (fh->m2m_ctx); -int ret; - -dev_dbg (dev,"DQBUF type=%d, index=%d" , buf->type, buf->index); -if (ctx->stopping ==1 && num_src_ready ==0 ) { -/* No more src bufs, notify app EOS */ -notify_eos (ctx); - ctx->stopping =0 ; -mxc_jpeg_set_last_buffer_dequeued (ctx); - } - - ret =v4l2_m2m_dqbuf (file, fh->m2m_ctx, buf); -return ret; -} -static const struct v4l2_ioctl_ops mxc_jpeg_ioctl_ops = { .vidioc_querycap = mxc_jpeg_querycap, .vidioc_enum_fmt_vid_cap = mxc_jpeg_enum_fmt_vid_cap,
@@ -1960,7 +1951,7 @@ static const struct v4l2_ioctl_ops mxc_jpeg_ioctl_ops = { .vidioc_encoder_cmd = mxc_jpeg_encoder_cmd, .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, - .vidioc_dqbuf = mxc_jpeg_dqbuf, + .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
drivers/media/platform/imx-jpeg/mxc-jpeg.h +0 -2
@@ -92,8 +92,6 @@ struct mxc_jpeg_ctx {struct mxc_jpeg_q_data cap_q;struct v4l2_fh fh;enum mxc_jpeg_enc_state enc_state; -unsigned int stopping; -unsigned int stopped;unsigned int slot;unsigned int source_change;bool header_parsed;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 279/779 ath9k: fix use-after-free in ath9k_hif_usb_rx_cb
In reply to Greg Kroah-HartmanFrom: Pavel Skripkin <[email protected]>
[ Upstream commit 0ac4827f78c7ffe8eef074bc010e7e34bc22f533 ]
Syzbot reported use-after-free Read in ath9k_hif_usb_rx_cb() [0]. The problem was in incorrect htc_handle->drv_priv initialization.
Probable call trace which can trigger use-after-free:
ath9k_htc_probe_device()
/* htc_handle->drv_priv = priv; */
ath9k_htc_wait_for_target() <--- Failed
ieee80211_free_hw() <--- priv pointer is freed
<IRQ>
...ath9k_hif_usb_rx_cb()
ath9k_hif_usb_rx_stream()
RX_STAT_INC() <--- htc_handle->drv_priv access
In order to not add fancy protection for drv_priv we can move htc_handle->drv_priv initialization at the end of the ath9k_htc_probe_device() and add helper macro to make
all *_STAT_* macros NULL safe, since syzbot has reported related NULL deref in that macros [1]
--- drivers/net/wireless/ath/ath9k/htc.h | 10 +++++----- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-)
drivers/net/wireless/ath/ath9k/htc.h +5 -5
@@ -327,11 +327,11 @@ static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb) }#ifdef CONFIG_ATH9K_HTC_DEBUGFS - -#define TX_STAT_INC (c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++) -#define TX_STAT_ADD (c, a) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c += a) -#define RX_STAT_INC (c) (hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c++) -#define RX_STAT_ADD (c, a) (hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c += a) +#define __STAT_SAFE (expr) (hif_dev->htc_handle->drv_priv ? (expr) : 0) +#define TX_STAT_INC (c) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.tx_stats.c++) +#define TX_STAT_ADD (c, a) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.tx_stats.c += a) +#define RX_STAT_INC (c) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c++) +#define RX_STAT_ADD (c, a) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c += a)#define CAB_STAT_INC priv->debug.tx_stats.cab_queued++#define TX_QSTAT_INC (q) (priv->debug.tx_stats.queue_stats[q]++)
drivers/net/wireless/ath/ath9k/htc_drv_init.c +2 -1
@@ -944,7 +944,6 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, priv->hw = hw; priv->htc = htc_handle; priv->dev = dev; - htc_handle->drv_priv = priv;SET_IEEE80211_DEV (hw, priv->dev); ret =ath9k_htc_wait_for_target (priv);
@@ -965,6 +964,8 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,if (ret) goto err_init; + htc_handle->drv_priv = priv; +return 0 ; err_init:
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 280/779 wifi: iwlegacy: 4965: fix potential off-by-one overflow in il4965_rs_fill_link_cmd()
In reply to Greg Kroah-HartmanFrom: Alexey Kodanev <[email protected]>
[ Upstream commit a8eb8e6f7159c7c20c0ddac428bde3d110890aa7 ]
As a result of the execution of the inner while loop, the value of 'idx' can be equal to LINK_QUAL_MAX_RETRY_NUM. However, this is not checked after the loop and 'idx' is used to write the LINK_QUAL_MAX_RETRY_NUM size array 'lq_cmd->rs_table[idx]' below in the outer loop.
The fix is to check the new value of 'idx' inside the nested loop, and break both loops if index equals the size. Checking it at the start is now pointless, so let's remove it.
Detected using the static analysis tool - Svace.
--- drivers/net/wireless/intel/iwlegacy/4965-rs.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/wireless/intel/iwlegacy/4965-rs.c +4 -1
@@ -2403,7 +2403,7 @@ il4965_rs_fill_link_cmd(struct il_priv *il, struct il_lq_sta *lq_sta,/* Repeat initial/next rate. * For legacy IL_NUMBER_TRY == 1, this loop will not execute. * For HT IL_HT_NUMBER_TRY == 3, this executes twice. */ -while (repeat_rate >0 && idx <LINK_QUAL_MAX_RETRY_NUM ) { +while (repeat_rate >0 ) {if (is_legacy (tbl_type.lq_type)) {if (ant_toggle_cnt <NUM_TRY_BEFORE_ANT_TOGGLE ) ant_toggle_cnt++;
@@ -2422,6 +2422,8 @@ il4965_rs_fill_link_cmd(struct il_priv *il, struct il_lq_sta *lq_sta,cpu_to_le32 (new_rate); repeat_rate--; idx++; +if (idx >=LINK_QUAL_MAX_RETRY_NUM ) + goto out; } il4965_rs_get_tbl_info_from_mcs(new_rate, lq_sta->band,
@@ -2466,6 +2468,7 @@ il4965_rs_fill_link_cmd(struct il_priv *il, struct il_lq_sta *lq_sta, repeat_rate--; } +out: lq_cmd->agg_params.agg_frame_cnt_limit =LINK_QUAL_AGG_FRAME_LIMIT_DEF ; lq_cmd->agg_params.agg_dis_start_th =LINK_QUAL_AGG_DISABLE_START_DEF ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 281/779 drm/radeon: fix incorrrect SPDX-License-Identifiers
In reply to Greg Kroah-HartmanFrom: Alex Deucher <[email protected]>
[ Upstream commit 1f43b8903f3aae4a26a603c36f6d5dd25d6edb51 ]
radeon is MIT. This were incorrectly changed in
commit b24413180f56 ("License cleanup: add SPDX GPL-2.0 license identifier to files with no license") and
commit d198b34f3855 (".gitignore: add SPDX License Identifier")
and:
commit ec8f24b7faaf ("treewide: Add SPDX license identifier - Makefile/Kconfig")
--- drivers/gpu/drm/radeon/.gitignore | 2 +- drivers/gpu/drm/radeon/Kconfig | 2 +- drivers/gpu/drm/radeon/Makefile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-)
drivers/gpu/drm/radeon/.gitignore +1 -1
@@ -1,4 +1,4 @@ -# SPDX-License-Identifier: GPL-2.0-only +# SPDX-License-Identifier: MIT mkregtable *_reg_safe.h
drivers/gpu/drm/radeon/Kconfig +1 -1
@@ -1,4 +1,4 @@ -# SPDX-License-Identifier: GPL-2.0-only +# SPDX-License-Identifier: MIT config DRM_RADEON_USERPTR bool "Always enable userptr support" depends on DRM_RADEON
drivers/gpu/drm/radeon/Makefile +1 -1
@@ -1,4 +1,4 @@ -# SPDX-License-Identifier: GPL-2.0 +# SPDX-License-Identifier: MIT # # Makefile for the drm device driver. This driver provides support for the # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 282/779 rcutorture: Warn on individual rcu_torture_init() error conditions
In reply to Greg Kroah-HartmanFrom: Paul E. McKenney <[email protected]>
[ Upstream commit efeff6b39b9de4480572c7b0c5eb77204795cb57 ]
When running rcutorture as a module, any rcu_torture_init() issues will be reflected in the error code from modprobe or insmod, as the case may be. However, these error codes are not available when running rcutorture built-in, for example, when using the kvm.sh script. This commit therefore adds WARN_ON_ONCE() to allow distinguishing rcu_torture_init() errors when running rcutorture built-in.
--- include/linux/torture.h | 8 ++++++++ kernel/rcu/rcutorture.c | 30 +++++++++++++++--------------- 2 files changed, 23 insertions(+), 15 deletions(-)
include/linux/torture.h +8 -0
@@ -47,6 +47,14 @@ do { \ }while (0 ) void verbose_torout_sleep(void); +#define torture_init_error (firsterr) \ +({ \ + int ___firsterr = (firsterr); \ + \ + WARN_ONCE(!IS_MODULE(CONFIG_RCU_TORTURE_TEST) && ___firsterr < 0, "Torture-test initialization failed with error code %d\n", ___firsterr); \ + ___firsterr < 0; \ +}) +/* Definitions for online/offline exerciser. */ #ifdef CONFIG_HOTPLUG_CPU int torture_num_online_cpus (void );
kernel/rcu/rcutorture.c +15 -15
@@ -3066,7 +3066,7 @@ rcu_torture_init(void)rcu_torture_write_types (); firsterr =torture_create_kthread (rcu_torture_writer,NULL , writer_task); -if (firsterr) +if (torture_init_error (firsterr)) goto unwind;if (nfakewriters >0 ) { fakewriter_tasks = kcalloc(nfakewriters,
@@ -3081,7 +3081,7 @@ rcu_torture_init(void)for (i =0 ; i < nfakewriters; i++) { firsterr =torture_create_kthread (rcu_torture_fakewriter,NULL , fakewriter_tasks[i]); -if (firsterr) +if (torture_init_error (firsterr)) goto unwind; } reader_tasks = kcalloc(nrealreaders, sizeof(reader_tasks[0]),
@@ -3097,7 +3097,7 @@ rcu_torture_init(void) rcu_torture_reader_mbchk[i].rtc_chkrdr =-1 ; firsterr =torture_create_kthread (rcu_torture_reader, (void *)i, reader_tasks[i]); -if (firsterr) +if (torture_init_error (firsterr)) goto unwind; } nrealnocbers = nocbs_nthreads;
@@ -3117,18 +3117,18 @@ rcu_torture_init(void) }for (i =0 ; i < nrealnocbers; i++) { firsterr =torture_create_kthread (rcu_nocb_toggle,NULL , nocb_tasks[i]); -if (firsterr) +if (torture_init_error (firsterr)) goto unwind; }if (stat_interval >0 ) { firsterr =torture_create_kthread (rcu_torture_stats,NULL , stats_task); -if (firsterr) +if (torture_init_error (firsterr)) goto unwind; }if (test_no_idle_hz && shuffle_interval >0 ) { firsterr =torture_shuffle_init (shuffle_interval *HZ ); -if (firsterr) +if (torture_init_error (firsterr)) goto unwind; }if (stutter <0 )
@@ -3138,7 +3138,7 @@ rcu_torture_init(void) t = cur_ops->stall_dur ? cur_ops->stall_dur () : stutter *HZ ; firsterr =torture_stutter_init (stutter *HZ , t); -if (firsterr) +if (torture_init_error (firsterr)) goto unwind; }if (fqs_duration <0 )
@@ -3147,7 +3147,7 @@ rcu_torture_init(void)/* Create the fqs thread */ firsterr =torture_create_kthread (rcu_torture_fqs,NULL , fqs_task); -if (firsterr) +if (torture_init_error (firsterr)) goto unwind; }if (test_boost_interval <1 )
@@ -3161,7 +3161,7 @@ rcu_torture_init(void) firsterr =cpuhp_setup_state (CPUHP_AP_ONLINE_DYN ,"RCU_TORTURE" , rcutorture_booster_init, rcutorture_booster_cleanup); -if (firsterr <0 ) +if (torture_init_error (firsterr)) goto unwind; rcutor_hp = firsterr;
@@ -3182,23 +3182,23 @@ rcu_torture_init(void) } shutdown_jiffies = jiffies + shutdown_secs *HZ ; firsterr =torture_shutdown_init (shutdown_secs, rcu_torture_cleanup); -if (firsterr) +if (torture_init_error (firsterr)) goto unwind; firsterr =torture_onoff_init (onoff_holdoff *HZ , onoff_interval, rcutorture_sync); -if (firsterr) +if (torture_init_error (firsterr)) goto unwind; firsterr =rcu_torture_stall_init (); -if (firsterr) +if (torture_init_error (firsterr)) goto unwind; firsterr =rcu_torture_fwd_prog_init (); -if (firsterr) +if (torture_init_error (firsterr)) goto unwind; firsterr =rcu_torture_barrier_init (); -if (firsterr) +if (torture_init_error (firsterr)) goto unwind; firsterr =rcu_torture_read_exit_init (); -if (firsterr) +if (torture_init_error (firsterr)) goto unwind;if (object_debug)rcu_test_debug_objects ();
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 283/779 rcutorture: Dont cpuhp_remove_state() if cpuhp_setup_state() failed
In reply to Greg Kroah-HartmanFrom: Paul E. McKenney <[email protected]>
[ Upstream commit fd13fe16db0d82612b260640f4e26f6d9d1e11fd ]
Currently, in CONFIG_RCU_BOOST kernels, if the rcu_torture_init() function's call to cpuhp_setup_state() fails, rcu_torture_cleanup() gamely passes nonsense to cpuhp_remove_state(). This results in strange and misleading splats. This commit therefore ensures that if the rcu_torture_init() function's call to cpuhp_setup_state() fails, rcu_torture_cleanup() avoids invoking cpuhp_remove_state().
--- kernel/rcu/rcutorture.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/rcu/rcutorture.c +2 -2
@@ -2848,7 +2848,7 @@ rcu_torture_cleanup(void) rcutorture_seq_diff(gp_seq, start_gp_seq));torture_stop_kthread (rcu_torture_stats, stats_task);torture_stop_kthread (rcu_torture_fqs, fqs_task); -if (rcu_torture_can_boost ()) +if (rcu_torture_can_boost () && rcutor_hp >=0 )cpuhp_remove_state (rcutor_hp);/*
@@ -3161,9 +3161,9 @@ rcu_torture_init(void) firsterr =cpuhp_setup_state (CPUHP_AP_ONLINE_DYN ,"RCU_TORTURE" , rcutorture_booster_init, rcutorture_booster_cleanup); + rcutor_hp = firsterr;if (torture_init_error (firsterr)) goto unwind; - rcutor_hp = firsterr;// Testing RCU priority boosting requires rcutorture do // some serious abuse. Counter this by running ksoftirqd
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 284/779 rcutorture: Fix ksoftirqd boosting timing and iteration
In reply to Greg Kroah-HartmanFrom: Frederic Weisbecker <[email protected]>
[ Upstream commit 3002153a91a9732a6d1d0bb95138593c7da15743 ]
The RCU priority boosting can fail in two situations:
1) If (nr_cpus= > maxcpus=), which means if the total number of CPUs is higher than those brought online at boot, then torture_onoff() may later bring up CPUs that weren't online on boot. Now since rcutorture initialization only boosts the ksoftirqds of the CPUs that have been set online on boot, the CPUs later set online by torture_onoff won't benefit from the boost, making RCU priority boosting fail.
2) The ksoftirqd kthreads are boosted after the creation of rcu_torture_boost() kthreads, which opens a window large enough for these rcu_torture_boost() kthreads to wait (despite running at FIFO priority) for ksoftirqds that are still running at SCHED_NORMAL priority.
The issues can trigger for example with:
./kvm.sh --configs TREE01 --kconfig "CONFIG_RCU_BOOST=y" [ 34.968561] rcu-torture: !!! [ 34.968627] ------------[ cut here ]------------ [ 35.014054] WARNING: CPU: 4 PID: 114 at kernel/rcu/rcutorture.c:1979 rcu_torture_stats_print+0x5ad/0x610 [ 35.052043] Modules linked in: [ 35.069138] CPU: 4 PID: 114 Comm: rcu_torture_sta Not tainted 5.18.0-rc1 #1 [ 35.096424] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.14.0-0-g155821a-rebuilt.opensuse.org 04/01/2014 [ 35.154570] RIP: 0010:rcu_torture_stats_print+0x5ad/0x610 [ 35.198527] Code: 63 1b 02 00 74 02 0f 0b 48 83 3d 35 63 1b 02 00 74 02 0f 0b 48 83 3d 21 63 1b 02 00 74 02 0f 0b 48 83 3d 0d 63 1b 02 00 74 02 <0f> 0b 83 eb 01 0f 8e ba fc ff ff 0f 0b e9 b3 fc ff f82 [ 37.251049] RSP: 0000:ffffa92a0050bdf8 EFLAGS: 00010202 [ 37.277320] rcu: De-offloading 8 [ 37.290367] RAX: 0000000000000000 RBX: 0000000000000001 RCX: 0000000000000001 [ 37.290387] RDX: 0000000000000000 RSI: 00000000ffffbfff RDI: 00000000ffffffff [ 37.290398] RBP: 000000000000007b R08: 0000000000000000 R09: c0000000ffffbfff [ 37.290407] R10: 000000000000002a R11: ffffa92a0050bc18 R12: ffffa92a0050be20 [ 37.290417] R13: ffffa92a0050be78 R14: 0000000000000000 R15: 000000000001bea0 [ 37.290427] FS: 0000000000000000(0000) GS:ffff96045eb00000(0000) knlGS:0000000000000000 [ 37.290448] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 37.290460] CR2: 0000000000000000 CR3: 000000001dc0c000 CR4: 00000000000006e0 [ 37.290470] Call Trace: [ 37.295049] <TASK> [ 37.295065] ? preempt_count_add+0x63/0x90 [ 37.295095] ? _raw_spin_lock_irqsave+0x12/0x40 [ 37.295125] ? rcu_torture_stats_print+0x610/0x610 [ 37.295143] rcu_torture_stats+0x29/0x70 [ 37.295160] kthread+0xe3/0x110 [ 37.295176] ? kthread_complete_and_exit+0x20/0x20 [ 37.295193] ret_from_fork+0x22/0x30 [ 37.295218] </TASK>
Fix this with boosting the ksoftirqds kthreads from the boosting hotplug callback itself and before the boosting kthreads are created.
--- kernel/rcu/rcutorture.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-)
kernel/rcu/rcutorture.c +13 -15
@@ -1991,6 +1991,19 @@ static int rcutorture_booster_init(unsigned int cpu)if (boost_tasks[cpu] !=NULL )return 0 ;/* Already created, nothing more to do. */ +// Testing RCU priority boosting requires rcutorture do +// some serious abuse. Counter this by running ksoftirqd +// at higher priority. +if (IS_BUILTIN (CONFIG_RCU_TORTURE_TEST )) { +struct sched_param sp; +struct task_struct *t; + + t =per_cpu (ksoftirqd, cpu); +WARN_ON_ONCE (!t); + sp.sched_priority =2 ; +sched_setscheduler_nocheck (t,SCHED_FIFO , &sp); + } +/* Don't allow time recalculation while creating a new task. */ mutex_lock (&boost_mutex);rcu_torture_disable_rt_throttle ();
@@ -3164,21 +3177,6 @@ rcu_torture_init(void) rcutor_hp = firsterr;if (torture_init_error (firsterr)) goto unwind; - -// Testing RCU priority boosting requires rcutorture do -// some serious abuse. Counter this by running ksoftirqd -// at higher priority. -if (IS_BUILTIN (CONFIG_RCU_TORTURE_TEST )) { -for_each_online_cpu (cpu) { -struct sched_param sp; -struct task_struct *t; - - t =per_cpu (ksoftirqd, cpu); -WARN_ON_ONCE (!t); - sp.sched_priority =2 ; -sched_setscheduler_nocheck (t,SCHED_FIFO , &sp); - } - } } shutdown_jiffies = jiffies + shutdown_secs *HZ ; firsterr =torture_shutdown_init (shutdown_secs, rcu_torture_cleanup);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 285/779 test_bpf: fix incorrect netdev features
In reply to Greg Kroah-HartmanFrom: Jian Shen <[email protected]>
[ Upstream commit 9676feccacdb0571791c88b23e3b7ac4e7c9c457 ]
The prototype of .features is netdev_features_t, it should use NETIF_F_LLTX and NETIF_F_HW_VLAN_STAG_TX, not NETIF_F_LLTX_BIT and NETIF_F_HW_VLAN_STAG_TX_BIT.
--- lib/test_bpf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
lib/test_bpf.c +2 -2
@@ -8890,9 +8890,9 @@ static struct skb_segment_test skb_segment_tests[] __initconst = { .build_skb = build_test_skb_linear_no_head_frag, .features =NETIF_F_SG |NETIF_F_FRAGLIST |NETIF_F_HW_VLAN_CTAG_TX |NETIF_F_GSO | -NETIF_F_LLTX_BIT |NETIF_F_GRO | +NETIF_F_LLTX |NETIF_F_GRO |NETIF_F_IPV6_CSUM |NETIF_F_RXCSUM | -NETIF_F_HW_VLAN_STAG_TX_BIT +NETIF_F_HW_VLAN_STAG_TX } };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 286/779 crypto: ccp - During shutdown, check SEV data pointer before using
In reply to Greg Kroah-HartmanFrom: Tom Lendacky <[email protected]>
[ Upstream commit 1b05ece0c931536c0a38a9385e243a7962e933f6 ]
On shutdown, each CCP device instance performs shutdown processing. However, __sev_platform_shutdown_locked() uses the controlling psp structure to obtain the pointer to the sev_device structure. However, during driver initialization, it is possible that an error can be received from the firmware that results in the sev_data pointer being cleared from the controlling psp structure. The __sev_platform_shutdown_locked() function does not check for this situation and will segfault.
While not common, this scenario should be accounted for. Add a check for a NULL sev_device structure before attempting to use it.
--- drivers/crypto/ccp/sev-dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/crypto/ccp/sev-dev.c +1 -1
@@ -314,7 +314,7 @@ static int __sev_platform_shutdown_locked(int *error)struct sev_device *sev = psp_master->sev_data;int ret; -if (sev->state ==SEV_STATE_UNINIT ) +if (!sev || sev->state ==SEV_STATE_UNINIT )return 0 ; ret =__sev_do_cmd_locked (SEV_CMD_SHUTDOWN ,NULL , error);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 287/779 drm: bridge: adv7511: Add check for mipi_dsi_driver_register
In reply to Greg Kroah-HartmanFrom: Jiasheng Jiang <[email protected]>
[ Upstream commit 831463667b5f4f1e5bce9c3b94e9e794d2bc8923 ]
As mipi_dsi_driver_register could return error if fails, it should be better to check the return value and return error if fails.
Moreover, if i2c_add_driver fails, mipi_dsi_driver_register should be reverted.
--- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +14 -3
@@ -1379,10 +1379,21 @@ static struct i2c_driver adv7511_driver = {static int __init adv7511_init (void ) { -if (IS_ENABLED (CONFIG_DRM_MIPI_DSI )) -mipi_dsi_driver_register (&adv7533_dsi_driver); +int ret; + +if (IS_ENABLED (CONFIG_DRM_MIPI_DSI )) { + ret =mipi_dsi_driver_register (&adv7533_dsi_driver); +if (ret) +return ret; + } -return i2c_add_driver (&adv7511_driver); + ret =i2c_add_driver (&adv7511_driver); +if (ret) { +if (IS_ENABLED (CONFIG_DRM_MIPI_DSI )) +mipi_dsi_driver_unregister (&adv7533_dsi_driver); + } + +return ret; }module_init (adv7511_init);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 288/779 media: imx-jpeg: Disable slot interrupt when frame done
In reply to Greg Kroah-HartmanFrom: Ming Qian <[email protected]>
[ Upstream commit 22a2bc88c139dc9757bdb1d0a3665ac27edc79a5 ]
The interrupt STMBUF_HALF may be triggered after frame done. It may led to system hang if driver try to access the register after power off.
Disable the slot interrupt when frame done.
--- drivers/media/platform/imx-jpeg/mxc-jpeg-hw.c | 5 +++++ drivers/media/platform/imx-jpeg/mxc-jpeg-hw.h | 1 + drivers/media/platform/imx-jpeg/mxc-jpeg.c | 10 ++-------- 3 files changed, 8 insertions(+), 8 deletions(-)
drivers/media/platform/imx-jpeg/mxc-jpeg-hw.c +5 -0
@@ -79,6 +79,11 @@ void mxc_jpeg_enable_irq(void __iomem *reg, int slot)writel (0xFFFFFFFF , reg +MXC_SLOT_OFFSET (slot,SLOT_IRQ_EN )); } +void mxc_jpeg_disable_irq (void __iomem *reg,int slot) +{ +writel (0x0 , reg +MXC_SLOT_OFFSET (slot,SLOT_IRQ_EN )); +} +void mxc_jpeg_sw_reset (void __iomem *reg) {/*
drivers/media/platform/imx-jpeg/mxc-jpeg-hw.h +1 -0
@@ -125,6 +125,7 @@ u32 mxc_jpeg_get_offset(void __iomem *reg, int slot);void mxc_jpeg_enable_slot (void __iomem *reg,int slot);void mxc_jpeg_set_l_endian (void __iomem *reg,int le);void mxc_jpeg_enable_irq (void __iomem *reg,int slot); +void mxc_jpeg_disable_irq (void __iomem *reg,int slot);int mxc_jpeg_set_input (void __iomem *reg,u32 in_buf,u32 bufsize);int mxc_jpeg_set_output (void __iomem *reg,u16 out_pitch,u32 out_buf,u16 w,u16 h);
drivers/media/platform/imx-jpeg/mxc-jpeg.c +2 -8
@@ -579,15 +579,8 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)dev_dbg (dev,"Irq %d on slot %d.\n" , irq, slot); ctx =v4l2_m2m_get_curr_priv (jpeg->m2m_dev); -if (!ctx) { -dev_err (dev, -"Instance released before the end of transaction.\n" ); -/* soft reset only resets internal state, not registers */ -mxc_jpeg_sw_reset (reg); -/* clear all interrupts */ -writel (0xFFFFFFFF , reg +MXC_SLOT_OFFSET (slot,SLOT_STATUS )); +if (WARN_ON (!ctx)) goto job_unlock; - }if (slot != ctx->slot) {/* TODO investigate when adding multi-instance support */
@@ -659,6 +652,7 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv) buf_state =VB2_BUF_STATE_DONE ; buffers_done: +mxc_jpeg_disable_irq (reg, ctx->slot); jpeg->slot_data[slot].used = false;/* unused, but don't free */ mxc_jpeg_check_and_set_last_buffer (ctx, src_buf, dst_buf);v4l2_m2m_src_buf_remove (ctx->fh.m2m_ctx);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 289/779 drm/mcde: Fix refcount leak in mcde_dsi_bind
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit 3a149169e4a2f9127022fec6ef5d71b4e804b3b9 ]
Every iteration of for_each_available_child_of_node() decrements the reference counter of the previous node. There is no decrement when break out from the loop and results in refcount leak. Add missing of_node_put() to fix this.
--- drivers/gpu/drm/mcde/mcde_dsi.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/mcde/mcde_dsi.c +1 -0
@@ -1111,6 +1111,7 @@ static int mcde_dsi_bind(struct device *dev, struct device *master, bridge =of_drm_find_bridge (child);if (!bridge) {dev_err (dev,"failed to find bridge\n" ); +of_node_put (child);return -EINVAL ; } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 290/779 media: hdpvr: fix error value returns in hdpvr_read
In reply to Greg Kroah-HartmanFrom: Niels Dossche <[email protected]>
[ Upstream commit 359c27c6ddbde404f44a9c0d3ec88ccd1e2042f2 ]
Error return values are supposed to be negative in hdpvr_read. Most error returns are currently handled via an unsigned integer "ret". When setting a negative error value to "ret", the value actually becomes a large positive value, because "ret" is unsigned. Later on, the "ret" value is returned. But as ssize_t is a 64-bit signed number, the error return value stays a large positive integer instead of a negative integer. This can cause an error value to be interpreted as the read size, which can cause a buffer overread for applications relying on the returned size.
--- drivers/media/usb/hdpvr/hdpvr-video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/usb/hdpvr/hdpvr-video.c +1 -1
@@ -409,7 +409,7 @@ static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count,struct hdpvr_device *dev =video_drvdata (file);struct hdpvr_buffer *buf =NULL ;struct urb *urb; -unsigned int ret =0 ; +int ret =0 ;int rem, cnt;if (*pos)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 291/779 media: v4l2-mem2mem: prevent pollerr when last_buffer_dequeued is set
In reply to Greg Kroah-HartmanFrom: Ming Qian <[email protected]>
[ Upstream commit d4de27a9b1eadd33a2e40de87a646d1bf5fef756 ]
If the last buffer was dequeued from the capture queue, signal userspace. DQBUF(CAPTURE) will return -EPIPE.
But if output queue is empty and capture queue is empty, v4l2_m2m_poll_for_data will return EPOLLERR, This is very easy to happen in drain.
When last_buffer_dequeued is set, we shouldn't return EPOLLERR, but return EPOLLIN | EPOLLRDNORM.
--- drivers/media/v4l2-core/v4l2-mem2mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/v4l2-core/v4l2-mem2mem.c +1 -1
@@ -924,7 +924,7 @@ static __poll_t v4l2_m2m_poll_for_data(struct file *file,if ((!src_q->streaming || src_q->error ||list_empty (&src_q->queued_list)) && (!dst_q->streaming || dst_q->error || -list_empty (&dst_q->queued_list))) + (list_empty (&dst_q->queued_list) && !dst_q->last_buffer_dequeued)))return EPOLLERR ;spin_lock_irqsave (&src_q->done_lock, flags);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 292/779 media: driver/nxp/imx-jpeg: fix a unexpected return value problem
In reply to Greg Kroah-HartmanFrom: Jian Zhang <[email protected]>
[ Upstream commit 5b304046a81eda221b5d06a9c62f7b5e45530fa5 ]
In function mxc_jpeg_probe(), when devm_clk_get() fail, the return value will be unexpected, and it should be the devm_clk_get's error code.
--- drivers/media/platform/imx-jpeg/mxc-jpeg.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/media/platform/imx-jpeg/mxc-jpeg.c +2 -0
@@ -2108,12 +2108,14 @@ static int mxc_jpeg_probe(struct platform_device *pdev) jpeg->clk_ipg =devm_clk_get (dev,"ipg" );if (IS_ERR (jpeg->clk_ipg)) {dev_err (dev,"failed to get clock: ipg\n" ); + ret =PTR_ERR (jpeg->clk_ipg); goto err_clk; } jpeg->clk_per =devm_clk_get (dev,"per" );if (IS_ERR (jpeg->clk_per)) {dev_err (dev,"failed to get clock: per\n" ); + ret =PTR_ERR (jpeg->clk_per); goto err_clk; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 293/779 media: tw686x: Fix memory leak in tw686x_video_init
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit e0b212ec9d8177d6f7c404315293f6a085d6ee42 ]
video_device_alloc() allocates memory for vdev,
when video_register_device() fails, it doesn't release the memory and leads to memory leak, call video_device_release() to fix this.
--- drivers/media/pci/tw686x/tw686x-video.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/media/pci/tw686x/tw686x-video.c +3 -1
@@ -1282,8 +1282,10 @@ int tw686x_video_init(struct tw686x_dev *dev)video_set_drvdata (vdev, vc); err =video_register_device (vdev,VFL_TYPE_VIDEO ,-1 ); -if (err <0 ) +if (err <0 ) { +video_device_release (vdev); goto error; + } vc->num = vdev->num; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 294/779 drm/vc4: plane: Remove subpixel positioning check
In reply to Greg Kroah-HartmanFrom: Dom Cobley <[email protected]>
[ Upstream commit 517db1ab1566dba3093dbdb8de4263ba4aa66416 ]
There is little harm in ignoring fractional coordinates (they just get truncated).
Without this:
modetest -M vc4 -F tiles,gradient -s 32:1920x1080-60 -P89@74:1920x1080*.1.1@XR24
is rejected. We have the same issue in Kodi when trying to use zoom options on video.
Note: even if all coordinates are fully integer. e.g. src:[0,0,1920,1080] dest:[-10,-10,1940,1100]
it will still get rejected as drm_atomic_helper_check_plane_state uses drm_rect_clip_scaled which transforms this to fractional src coords
--- drivers/gpu/drm/vc4/vc4_plane.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-)
drivers/gpu/drm/vc4/vc4_plane.c +9 -13
@@ -332,7 +332,6 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state)struct vc4_plane_state *vc4_state =to_vc4_plane_state (state);struct drm_framebuffer *fb = state->fb;struct drm_gem_cma_object *bo =drm_fb_cma_get_gem_obj (fb,0 ); -u32 subpixel_src_mask = (1 <<16 ) -1 ;int num_planes = fb->format->num_planes;struct drm_crtc_state *crtc_state;u32 h_subsample = fb->format->hsub;
@@ -354,18 +353,15 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state)for (i =0 ; i < num_planes; i++) vc4_state->offsets[i] = bo->paddr + fb->offsets[i]; -/* We don't support subpixel source positioning for scaling. */ -if ((state->src.x1 & subpixel_src_mask) || - (state->src.x2 & subpixel_src_mask) || - (state->src.y1 & subpixel_src_mask) || - (state->src.y2 & subpixel_src_mask)) { -return -EINVAL ; - } - - vc4_state->src_x = state->src.x1 >>16 ; - vc4_state->src_y = state->src.y1 >>16 ; - vc4_state->src_w[0 ] = (state->src.x2 - state->src.x1) >>16 ; - vc4_state->src_h[0 ] = (state->src.y2 - state->src.y1) >>16 ; +/* +* We don't support subpixel source positioning for scaling, +* but fractional coordinates can be generated by clipping +* so just round for now +*/ + vc4_state->src_x =DIV_ROUND_CLOSEST (state->src.x1,1 <<16 ); + vc4_state->src_y =DIV_ROUND_CLOSEST (state->src.y1,1 <<16 ); + vc4_state->src_w[0 ] =DIV_ROUND_CLOSEST (state->src.x2,1 <<16 ) - vc4_state->src_x; + vc4_state->src_h[0 ] =DIV_ROUND_CLOSEST (state->src.y2,1 <<16 ) - vc4_state->src_y; vc4_state->crtc_x = state->dst.x1; vc4_state->crtc_y = state->dst.y1;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 295/779 drm/vc4: plane: Fix margin calculations for the right/bottom edges
In reply to Greg Kroah-HartmanFrom: Dave Stevenson <[email protected]>
[ Upstream commit b7c3d6821627861f4ea3e1f2b595d0ed9e80aac8 ]
The current plane margin calculation code clips the right and bottom edges of the range based using the left and top margins.
This is obviously wrong, so let's fix it.
--- drivers/gpu/drm/vc4/vc4_plane.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/gpu/drm/vc4/vc4_plane.c +4 -4
@@ -303,16 +303,16 @@ static int vc4_plane_margins_adj(struct drm_plane_state *pstate) adjhdisplay, crtc_state->mode.hdisplay); vc4_pstate->crtc_x += left; -if (vc4_pstate->crtc_x > crtc_state->mode.hdisplay - left) - vc4_pstate->crtc_x = crtc_state->mode.hdisplay - left; +if (vc4_pstate->crtc_x > crtc_state->mode.hdisplay - right) + vc4_pstate->crtc_x = crtc_state->mode.hdisplay - right; adjvdisplay = crtc_state->mode.vdisplay - (top + bottom); vc4_pstate->crtc_y =DIV_ROUND_CLOSEST (vc4_pstate->crtc_y * adjvdisplay, crtc_state->mode.vdisplay); vc4_pstate->crtc_y += top; -if (vc4_pstate->crtc_y > crtc_state->mode.vdisplay - top) - vc4_pstate->crtc_y = crtc_state->mode.vdisplay - top; +if (vc4_pstate->crtc_y > crtc_state->mode.vdisplay - bottom) + vc4_pstate->crtc_y = crtc_state->mode.vdisplay - bottom; vc4_pstate->crtc_w = DIV_ROUND_CLOSEST(vc4_pstate->crtc_w * adjhdisplay,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 296/779 drm/bridge: Add a function to abstract away panels
In reply to Greg Kroah-HartmanFrom: Maxime Ripard <[email protected]>
[ Upstream commit 87ea95808d53e56b03e620e8f8f3add48899a88d ]
Display drivers so far need to have a lot of boilerplate to first retrieve either the panel or bridge that they are connected to using drm_of_find_panel_or_bridge(), and then either deal with each with ad-hoc functions or create a drm panel bridge through drm_panel_bridge_add.
In order to reduce the boilerplate and hopefully create a path of least resistance towards using the DRM panel bridge layer, let's create the function devm_drm_of_get_bridge() to reduce that boilerplate.
--- drivers/gpu/drm/drm_bridge.c | 41 ++++++++++++++++++++++++++++++++---- drivers/gpu/drm/drm_of.c | 3 +++ include/drm/drm_bridge.h | 2 ++ 3 files changed, 42 insertions(+), 4 deletions(-)
drivers/gpu/drm/drm_bridge.c +37 -4
@@ -28,6 +28,7 @@#include <drm/drm_atomic_state_helper.h> #include <drm/drm_bridge.h> #include <drm/drm_encoder.h> +#include <drm/drm_of.h> #include <drm/drm_print.h> #include "drm_crtc_internal.h"
@@ -51,10 +52,8 @@* * Display drivers are responsible for linking encoders with the first bridge * in the chains. This is done by acquiring the appropriate bridge with -* of_drm_find_bridge() or drm_of_find_panel_or_bridge(), or creating it for a -* panel with drm_panel_bridge_add_typed() (or the managed version -* devm_drm_panel_bridge_add_typed()). Once acquired, the bridge shall be -* attached to the encoder with a call to drm_bridge_attach(). +* devm_drm_of_get_bridge(). Once acquired, the bridge shall be attached to the +* encoder with a call to drm_bridge_attach(). * * Bridges are responsible for linking themselves with the next bridge in the * chain, if any. This is done the same way as for encoders, with the call to
@@ -1233,6 +1232,40 @@ struct drm_bridge *of_drm_find_bridge(struct device_node *np) return NULL; }EXPORT_SYMBOL (of_drm_find_bridge); + +/** +* devm_drm_of_get_bridge - Return next bridge in the chain +* @dev: device to tie the bridge lifetime to +* @np: device tree node containing encoder output ports +* @port: port in the device tree node +* @endpoint: endpoint in the device tree node +* +* Given a DT node's port and endpoint number, finds the connected node +* and returns the associated bridge if any, or creates and returns a +* drm panel bridge instance if a panel is connected. +* +* Returns a pointer to the bridge if successful, or an error pointer +* otherwise. +*/ +struct drm_bridge *devm_drm_of_get_bridge (struct device *dev, +struct device_node *np, +u32 port,u32 endpoint) +{ +struct drm_bridge *bridge; +struct drm_panel *panel; +int ret; + + ret =drm_of_find_panel_or_bridge (np, port, endpoint, + &panel, &bridge); +if (ret) +return ERR_PTR (ret); + +if (panel) + bridge =devm_drm_panel_bridge_add (dev, panel); + +return bridge; +} +EXPORT_SYMBOL (devm_drm_of_get_bridge);#endif MODULE_AUTHOR ("Ajay Kumar <[email protected]>" );
drivers/gpu/drm/drm_of.c +3 -0
@@ -231,6 +231,9 @@ EXPORT_SYMBOL_GPL(drm_of_encoder_active_endpoint);* return either the associated struct drm_panel or drm_bridge device. Either * @panel or @bridge must not be NULL. * +* This function is deprecated and should not be used in new drivers. Use +* devm_drm_of_get_bridge() instead. +* * Returns zero if successful, or one of the standard error codes if it fails. */ int drm_of_find_panel_or_bridge(const struct device_node *np,
include/drm/drm_bridge.h +2 -0
@@ -911,6 +911,8 @@ struct drm_bridge *devm_drm_panel_bridge_add(struct device *dev,struct drm_bridge *devm_drm_panel_bridge_add_typed (struct device *dev,struct drm_panel *panel,u32 connector_type); +struct drm_bridge *devm_drm_of_get_bridge (struct device *dev,struct device_node *node, +u32 port,u32 endpoint);struct drm_connector *drm_panel_bridge_connector (struct drm_bridge *bridge);#endif
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 297/779 drm/vc4: dsi: Switch to devm_drm_of_get_bridge
In reply to Greg Kroah-HartmanFrom: Maxime Ripard <[email protected]>
[ Upstream commit a43dd76bacd0d5441a4c84f60d64bdfaedc95bac ]
The new devm_drm_of_get_bridge removes most of the boilerplate we have to deal with. Let's switch to it.
--- drivers/gpu/drm/vc4/vc4_dsi.c | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-)
drivers/gpu/drm/vc4/vc4_dsi.c +4 -24
@@ -1493,7 +1493,6 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)struct drm_device *drm =dev_get_drvdata (master);struct vc4_dsi *dsi =dev_get_drvdata (dev);struct vc4_dsi_encoder *vc4_dsi_encoder; -struct drm_panel *panel;const struct of_device_id *match;dma_cap_mask_t dma_mask;int ret;
@@ -1605,27 +1604,9 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)return ret; } - ret =drm_of_find_panel_or_bridge (dev->of_node,0 ,0 , - &panel, &dsi->bridge); -if (ret) { -/* If the bridge or panel pointed by dev->of_node is not -* enabled, just return 0 here so that we don't prevent the DRM -* dev from being registered. Of course that means the DSI -* encoder won't be exposed, but that's not a problem since -* nothing is connected to it. -*/ -if (ret == -ENODEV ) -return 0 ; - -return ret; - } - -if (panel) { - dsi->bridge =devm_drm_panel_bridge_add_typed (dev, panel, -DRM_MODE_CONNECTOR_DSI ); -if (IS_ERR (dsi->bridge)) -return PTR_ERR (dsi->bridge); - } + dsi->bridge =devm_drm_of_get_bridge (dev, dev->of_node,0 ,0 ); +if (IS_ERR (dsi->bridge)) +return PTR_ERR (dsi->bridge);/* The esc clock rate is supposed to always be 100Mhz. */ ret =clk_set_rate (dsi->escape_clock,100 *1000000 );
@@ -1663,8 +1644,7 @@ static void vc4_dsi_unbind(struct device *dev, struct device *master, {struct vc4_dsi *dsi =dev_get_drvdata (dev); -if (dsi->bridge) -pm_runtime_disable (dev); +pm_runtime_disable (dev);/* * Restore the bridge_chain so the bridge detach procedure can happen
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 298/779 drm/vc4: Use of_device_get_match_data()
In reply to Greg Kroah-HartmanFrom: Minghao Chi (CGEL ZTE) <[email protected]>
[ Upstream commit 9cbe89ede58294d23af06ec12c20f2ce6acc1892 ]
Use of_device_get_match_data() to simplify the code.
--- drivers/gpu/drm/vc4/vc4_dsi.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
drivers/gpu/drm/vc4/vc4_dsi.c +1 -6
@@ -1493,15 +1493,10 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)struct drm_device *drm =dev_get_drvdata (master);struct vc4_dsi *dsi =dev_get_drvdata (dev);struct vc4_dsi_encoder *vc4_dsi_encoder; -const struct of_device_id *match;dma_cap_mask_t dma_mask;int ret; - match =of_match_device (vc4_dsi_dt_match, dev); -if (!match) -return -ENODEV ; - - dsi->variant = match->data; + dsi->variant =of_device_get_match_data (dev); vc4_dsi_encoder =devm_kzalloc (dev,sizeof (*vc4_dsi_encoder),GFP_KERNEL );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 299/779 drm/vc4: dsi: Release workaround buffer and DMA
In reply to Greg Kroah-HartmanFrom: Dave Stevenson <[email protected]>
[ Upstream commit 89c4bbe2a01ea401c2b0fabc104720809084b77f ]
On Pi0-3 the driver allocates a buffer and requests a DMA channel because the ARM can't write to DSI1's registers directly.
However, we never release that buffer or channel. Let's add a device-managed action to release each.
--- drivers/gpu/drm/vc4/vc4_dsi.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-)
drivers/gpu/drm/vc4/vc4_dsi.c +28 -1
@@ -1487,13 +1487,29 @@ vc4_dsi_init_phy_clocks(struct vc4_dsi *dsi) dsi->clk_onecell); } +static void vc4_dsi_dma_mem_release (void *ptr) +{ +struct vc4_dsi *dsi = ptr; +struct device *dev = &dsi->pdev->dev; + +dma_free_coherent (dev,4 , dsi->reg_dma_mem, dsi->reg_dma_paddr); + dsi->reg_dma_mem =NULL ; +} + +static void vc4_dsi_dma_chan_release (void *ptr) +{ +struct vc4_dsi *dsi = ptr; + +dma_release_channel (dsi->reg_dma_chan); + dsi->reg_dma_chan =NULL ; +} +static int vc4_dsi_bind (struct device *dev,struct device *master,void *data) {struct platform_device *pdev =to_platform_device (dev);struct drm_device *drm =dev_get_drvdata (master);struct vc4_dsi *dsi =dev_get_drvdata (dev);struct vc4_dsi_encoder *vc4_dsi_encoder; -dma_cap_mask_t dma_mask;int ret; dsi->variant =of_device_get_match_data (dev);
@@ -1527,6 +1543,8 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)* so set up a channel for talking to it. */ if (dsi->variant->broken_axi_workaround) { +dma_cap_mask_t dma_mask; + dsi->reg_dma_mem =dma_alloc_coherent (dev,4 , &dsi->reg_dma_paddr,GFP_KERNEL );
@@ -1535,8 +1553,13 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)return -ENOMEM ; } + ret =devm_add_action_or_reset (dev, vc4_dsi_dma_mem_release, dsi); +if (ret) +return ret; +dma_cap_zero (dma_mask);dma_cap_set (DMA_MEMCPY , dma_mask); + dsi->reg_dma_chan =dma_request_chan_by_mask (&dma_mask);if (IS_ERR (dsi->reg_dma_chan)) { ret =PTR_ERR (dsi->reg_dma_chan);
@@ -1546,6 +1569,10 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)return ret; } + ret =devm_add_action_or_reset (dev, vc4_dsi_dma_chan_release, dsi); +if (ret) +return ret; +/* Get the physical address of the device's registers. The * struct resource for the regs gives us the bus address * instead.
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 300/779 drm/vc4: dsi: Correct DSI divider calculations
In reply to Greg Kroah-HartmanFrom: Dave Stevenson <[email protected]>
[ Upstream commit 3b45eee87da171caa28f61240ddb5c21170cda53 ]
The divider calculations tried to find the divider just faster than the clock requested. However if it required a divider of 7 then the for loop aborted without handling the "error" case, and could end up with a clock lower than requested.
The integer divider from parent PLL to DSI clock is also capable of going up to /255, not just /7 that the driver was trying. This allows for slower link frequencies on the DSI bus where the resolution permits.
Correct the loop so that we always have a clock greater than requested, and covering the whole range of dividers.
--- drivers/gpu/drm/vc4/vc4_dsi.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/gpu/drm/vc4/vc4_dsi.c +2 -4
@@ -805,11 +805,9 @@ static bool vc4_dsi_encoder_mode_fixup(struct drm_encoder *encoder,/* Find what divider gets us a faster clock than the requested * pixel clock. */ -for (divider =1 ; divider <8 ; divider++) { -if (parent_rate / divider < pll_clock) { - divider--; +for (divider =1 ; divider <255 ; divider++) { +if (parent_rate / (divider +1 ) < pll_clock)break ; - } }/* Now that we've picked a PLL divider, calculate back to its
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 301/779 drm/vc4: dsi: Correct pixel order for DSI0
In reply to Greg Kroah-HartmanFrom: Dave Stevenson <[email protected]>
[ Upstream commit edfe84ae0df16be1251b5a8e840d95f1f3827500 ]
For slightly unknown reasons, dsi0 takes a different pixel format to dsi1, and that has to be set in the pixel valve.
Amend the setup accordingly.
--- drivers/gpu/drm/vc4/vc4_crtc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/vc4/vc4_crtc.c +2 -1
@@ -330,7 +330,8 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_atomic_state *su32 pixel_rep = (mode->flags &DRM_MODE_FLAG_DBLCLK ) ?2 :1 ;bool is_dsi = (vc4_encoder->type ==VC4_ENCODER_TYPE_DSI0 || vc4_encoder->type ==VC4_ENCODER_TYPE_DSI1 ); -u32 format = is_dsi ?PV_CONTROL_FORMAT_DSIV_24 :PV_CONTROL_FORMAT_24 ; +bool is_dsi1 = vc4_encoder->type ==VC4_ENCODER_TYPE_DSI1 ; +u32 format = is_dsi1 ?PV_CONTROL_FORMAT_DSIV_24 :PV_CONTROL_FORMAT_24 ;u8 ppc = pv_data->pixels_per_clock;bool debug_dump_regs = false;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 302/779 drm/vc4: dsi: Register dsi0 as the correct vc4 encoder type
In reply to Greg Kroah-HartmanFrom: Dave Stevenson <[email protected]>
[ Upstream commit 4d9273c978d4c1af15d7874c10c732ec83d444d0 ]
vc4_dsi was registering both dsi0 and dsi1 as VC4_ENCODER_TYPE_DSI1 which seemed to work OK for a single DSI display, but fails if there are two DSI displays connected.
Update to register the correct type.
--- drivers/gpu/drm/vc4/vc4_dsi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/vc4/vc4_dsi.c +2 -1
@@ -1518,7 +1518,8 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)return -ENOMEM ;INIT_LIST_HEAD (&dsi->bridge_chain); - vc4_dsi_encoder->base.type =VC4_ENCODER_TYPE_DSI1 ; + vc4_dsi_encoder->base.type = dsi->variant->port ? +VC4_ENCODER_TYPE_DSI1 :VC4_ENCODER_TYPE_DSI0 ; vc4_dsi_encoder->dsi = dsi; dsi->encoder = &vc4_dsi_encoder->base.base;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 303/779 drm/vc4: dsi: Fix dsi0 interrupt support
In reply to Greg Kroah-HartmanFrom: Dave Stevenson <[email protected]>
[ Upstream commit bc5b815e06f90cccdb6461aba1e49fdc2f3c8cd1 ]
DSI0 seemingly had very little or no testing as a load of the register mappings were incorrect/missing, so host transfers always timed out due to enabling/checking incorrect bits in the interrupt enable and status registers.
--- drivers/gpu/drm/vc4/vc4_dsi.c | 111 ++++++++++++++++++++++++++-------- 1 file changed, 85 insertions(+), 26 deletions(-)
drivers/gpu/drm/vc4/vc4_dsi.c +85 -26
@@ -181,8 +181,50 @@#define DSI0_TXPKT_PIX_FIFO 0x20/* AKA PIX_FIFO */ -#define DSI0_INT_STAT 0x24 -#define DSI0_INT_EN 0x28 +#define DSI0_INT_STAT 0x24 +#define DSI0_INT_EN 0x28 +# define DSI0_INT_FIFO_ERR BIT(25) +# define DSI0_INT_CMDC_DONE_MASK VC4_MASK(24, 23) +# define DSI0_INT_CMDC_DONE_SHIFT 23 +# define DSI0_INT_CMDC_DONE_NO_REPEAT 1 +# define DSI0_INT_CMDC_DONE_REPEAT 3 +# define DSI0_INT_PHY_DIR_RTF BIT(22) +# define DSI0_INT_PHY_D1_ULPS BIT(21) +# define DSI0_INT_PHY_D1_STOP BIT(20) +# define DSI0_INT_PHY_RXLPDT BIT(19) +# define DSI0_INT_PHY_RXTRIG BIT(18) +# define DSI0_INT_PHY_D0_ULPS BIT(17) +# define DSI0_INT_PHY_D0_LPDT BIT(16) +# define DSI0_INT_PHY_D0_FTR BIT(15) +# define DSI0_INT_PHY_D0_STOP BIT(14) +/* Signaled when the clock lane enters the given state. */ +# define DSI0_INT_PHY_CLK_ULPS BIT(13) +# define DSI0_INT_PHY_CLK_HS BIT(12) +# define DSI0_INT_PHY_CLK_FTR BIT(11) +/* Signaled on timeouts */ +# define DSI0_INT_PR_TO BIT(10) +# define DSI0_INT_TA_TO BIT(9) +# define DSI0_INT_LPRX_TO BIT(8) +# define DSI0_INT_HSTX_TO BIT(7) +/* Contention on a line when trying to drive the line low */ +# define DSI0_INT_ERR_CONT_LP1 BIT(6) +# define DSI0_INT_ERR_CONT_LP0 BIT(5) +/* Control error: incorrect line state sequence on data lane 0. */ +# define DSI0_INT_ERR_CONTROL BIT(4) +# define DSI0_INT_ERR_SYNC_ESC BIT(3) +# define DSI0_INT_RX2_PKT BIT(2) +# define DSI0_INT_RX1_PKT BIT(1) +# define DSI0_INT_CMD_PKT BIT(0) + +#define DSI0_INTERRUPTS_ALWAYS_ENABLED (DSI0_INT_ERR_SYNC_ESC | \ + DSI0_INT_ERR_CONTROL | \ + DSI0_INT_ERR_CONT_LP0 | \ + DSI0_INT_ERR_CONT_LP1 | \ + DSI0_INT_HSTX_TO | \ + DSI0_INT_LPRX_TO | \ + DSI0_INT_TA_TO | \ + DSI0_INT_PR_TO) +# define DSI1_INT_PHY_D3_ULPS BIT(30)# define DSI1_INT_PHY_D3_STOP BIT(29)# define DSI1_INT_PHY_D2_ULPS BIT(28)
@@ -892,6 +934,9 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder)DSI_PORT_WRITE (PHY_AFEC0 , afec0); +/* AFEC reset hold time */ +mdelay (1 ); + DSI_PORT_WRITE(PHY_AFEC1, VC4_SET_FIELD(6, DSI0_PHY_AFEC1_IDR_DLANE1) | VC4_SET_FIELD(6, DSI0_PHY_AFEC1_IDR_DLANE0) |
@@ -1058,12 +1103,9 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder)DSI_PORT_WRITE (CTRL ,DSI_PORT_READ (CTRL ) |DSI1_CTRL_EN );/* Bring AFE out of reset. */ -if (dsi->variant->port ==0 ) { - }else { -DSI_PORT_WRITE (PHY_AFEC0 , -DSI_PORT_READ (PHY_AFEC0 ) & - ~DSI1_PHY_AFEC0_RESET ); - } +DSI_PORT_WRITE (PHY_AFEC0 , +DSI_PORT_READ (PHY_AFEC0 ) & + ~DSI_PORT_BIT (PHY_AFEC0_RESET ));vc4_dsi_ulps (dsi, false);
@@ -1182,13 +1224,28 @@ static ssize_t vc4_dsi_host_transfer(struct mipi_dsi_host *host,/* Enable the appropriate interrupt for the transfer completion. */ dsi->xfer_result =0 ;reinit_completion (&dsi->xfer_completion); -DSI_PORT_WRITE (INT_STAT ,DSI1_INT_TXPKT1_DONE |DSI1_INT_PHY_DIR_RTF ); -if (msg->rx_len) { -DSI_PORT_WRITE (INT_EN , (DSI1_INTERRUPTS_ALWAYS_ENABLED | -DSI1_INT_PHY_DIR_RTF )); +if (dsi->variant->port ==0 ) { +DSI_PORT_WRITE (INT_STAT , +DSI0_INT_CMDC_DONE_MASK |DSI1_INT_PHY_DIR_RTF ); +if (msg->rx_len) { +DSI_PORT_WRITE (INT_EN , (DSI0_INTERRUPTS_ALWAYS_ENABLED | +DSI0_INT_PHY_DIR_RTF )); + }else { +DSI_PORT_WRITE (INT_EN , + (DSI0_INTERRUPTS_ALWAYS_ENABLED | +VC4_SET_FIELD (DSI0_INT_CMDC_DONE_NO_REPEAT , +DSI0_INT_CMDC_DONE ))); + } }else { -DSI_PORT_WRITE (INT_EN , (DSI1_INTERRUPTS_ALWAYS_ENABLED | -DSI1_INT_TXPKT1_DONE )); +DSI_PORT_WRITE (INT_STAT , +DSI1_INT_TXPKT1_DONE |DSI1_INT_PHY_DIR_RTF ); +if (msg->rx_len) { +DSI_PORT_WRITE (INT_EN , (DSI1_INTERRUPTS_ALWAYS_ENABLED | +DSI1_INT_PHY_DIR_RTF )); + }else { +DSI_PORT_WRITE (INT_EN , (DSI1_INTERRUPTS_ALWAYS_ENABLED | +DSI1_INT_TXPKT1_DONE )); + } }/* Send the packet. */
@@ -1205,7 +1262,7 @@ static ssize_t vc4_dsi_host_transfer(struct mipi_dsi_host *host, ret = dsi->xfer_result; } -DSI_PORT_WRITE (INT_EN ,DSI1_INTERRUPTS_ALWAYS_ENABLED ); +DSI_PORT_WRITE (INT_EN ,DSI_PORT_BIT (INTERRUPTS_ALWAYS_ENABLED ));if (ret) goto reset_fifo_and_return;
@@ -1251,7 +1308,7 @@ static ssize_t vc4_dsi_host_transfer(struct mipi_dsi_host *host, DSI_PORT_BIT(CTRL_RESET_FIFOS));DSI_PORT_WRITE (TXPKT1C ,0 ); -DSI_PORT_WRITE (INT_EN ,DSI1_INTERRUPTS_ALWAYS_ENABLED ); +DSI_PORT_WRITE (INT_EN ,DSI_PORT_BIT (INTERRUPTS_ALWAYS_ENABLED ));return ret; }
@@ -1388,26 +1445,28 @@ static irqreturn_t vc4_dsi_irq_handler(int irq, void *data)DSI_PORT_WRITE (INT_STAT , stat);dsi_handle_error (dsi, &ret, stat, -DSI1_INT_ERR_SYNC_ESC ,"LPDT sync" ); +DSI_PORT_BIT (INT_ERR_SYNC_ESC ),"LPDT sync" );dsi_handle_error (dsi, &ret, stat, -DSI1_INT_ERR_CONTROL ,"data lane 0 sequence" ); +DSI_PORT_BIT (INT_ERR_CONTROL ),"data lane 0 sequence" );dsi_handle_error (dsi, &ret, stat, -DSI1_INT_ERR_CONT_LP0 ,"LP0 contention" ); +DSI_PORT_BIT (INT_ERR_CONT_LP0 ),"LP0 contention" );dsi_handle_error (dsi, &ret, stat, -DSI1_INT_ERR_CONT_LP1 ,"LP1 contention" ); +DSI_PORT_BIT (INT_ERR_CONT_LP1 ),"LP1 contention" );dsi_handle_error (dsi, &ret, stat, -DSI1_INT_HSTX_TO ,"HSTX timeout" ); +DSI_PORT_BIT (INT_HSTX_TO ),"HSTX timeout" );dsi_handle_error (dsi, &ret, stat, -DSI1_INT_LPRX_TO ,"LPRX timeout" ); +DSI_PORT_BIT (INT_LPRX_TO ),"LPRX timeout" );dsi_handle_error (dsi, &ret, stat, -DSI1_INT_TA_TO ,"turnaround timeout" ); +DSI_PORT_BIT (INT_TA_TO ),"turnaround timeout" );dsi_handle_error (dsi, &ret, stat, -DSI1_INT_PR_TO ,"peripheral reset timeout" ); +DSI_PORT_BIT (INT_PR_TO ),"peripheral reset timeout" ); -if (stat & (DSI1_INT_TXPKT1_DONE |DSI1_INT_PHY_DIR_RTF )) { +if (stat & ((dsi->variant->port ?DSI1_INT_TXPKT1_DONE : +DSI0_INT_CMDC_DONE_MASK ) | +DSI_PORT_BIT (INT_PHY_DIR_RTF ))) {complete (&dsi->xfer_completion); ret =IRQ_HANDLED ; - }else if (stat &DSI1_INT_HSTX_TO ) { + }else if (stat &DSI_PORT_BIT (INT_HSTX_TO )) {complete (&dsi->xfer_completion); dsi->xfer_result = -ETIMEDOUT ; ret =IRQ_HANDLED ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 304/779 drm/vc4: dsi: Add correct stop condition to vc4_dsi_encoder_disable iteration
In reply to Greg Kroah-HartmanFrom: Dave Stevenson <[email protected]>
[ Upstream commit 7bcb9c8d0bc9f3cab8ac2634b056c2e6b63945ca ]
vc4_dsi_encoder_disable is partially an open coded version of drm_bridge_chain_disable, but it missed a termination condition in the loop for ->disable which meant that no post_disable calls were made.
Add in the termination clause.
--- drivers/gpu/drm/vc4/vc4_dsi.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/vc4/vc4_dsi.c +3 -0
@@ -803,6 +803,9 @@ static void vc4_dsi_encoder_disable(struct drm_encoder *encoder)list_for_each_entry_reverse (iter, &dsi->bridge_chain, chain_node) {if (iter->funcs->disable) iter->funcs->disable (iter); + +if (iter == dsi->bridge) +break ; }vc4_dsi_ulps (dsi, true);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 305/779 drm/vc4: hdmi: Fix HPD GPIO detection
In reply to Greg Kroah-HartmanFrom: Maxime Ripard <[email protected]>
[ Upstream commit e32e5723256a99c5324824503572f743377dd0fe ]
Prior to commit 6800234ceee0 ("drm/vc4: hdmi: Convert to gpiod"), in the detect hook, if we had an HPD GPIO we would only rely on it and return whatever state it was in.
However, that commit changed that by mistake to only consider the case where we have a GPIO and it returns a logical high, and would fall back to the other methods otherwise.
Since we can read the EDIDs when the HPD signal is low on some displays, we changed the detection status from disconnected to connected, and we would ignore an HPD pulse.
--- drivers/gpu/drm/vc4/vc4_hdmi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/gpu/drm/vc4/vc4_hdmi.c +3 -3
@@ -173,9 +173,9 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)WARN_ON (pm_runtime_resume_and_get (&vc4_hdmi->pdev->dev)); -if (vc4_hdmi->hpd_gpio && -gpiod_get_value_cansleep (vc4_hdmi->hpd_gpio)) { - connected = true; +if (vc4_hdmi->hpd_gpio) { +if (gpiod_get_value_cansleep (vc4_hdmi->hpd_gpio)) + connected = true; }else if (drm_probe_ddc (vc4_hdmi->ddc)) { connected = true; }else if (HDMI_READ (HDMI_HOTPLUG ) &VC4_HDMI_HOTPLUG_CONNECTED ) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 306/779 drm/vc4: hdmi: Avoid full hdmi audio fifo writes
In reply to Greg Kroah-HartmanFrom: Dom Cobley <[email protected]>
[ Upstream commit 1c594eeccf92368177c2e22f1d3ee4933dfb8567 ]
We are getting occasional VC4_HD_MAI_CTL_ERRORF in HDMI_MAI_CTL which seem to correspond with audio dropouts.
Reduce the threshold where we deassert DREQ to avoid the fifo overfilling
--- drivers/gpu/drm/vc4/vc4_hdmi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/gpu/drm/vc4/vc4_hdmi.c +4 -4
@@ -1383,10 +1383,10 @@ static int vc4_hdmi_audio_prepare(struct device *dev, void *data,/* Set the MAI threshold */ HDMI_WRITE (HDMI_MAI_THR , -VC4_SET_FIELD (0x10 ,VC4_HD_MAI_THR_PANICHIGH ) | -VC4_SET_FIELD (0x10 ,VC4_HD_MAI_THR_PANICLOW ) | -VC4_SET_FIELD (0x10 ,VC4_HD_MAI_THR_DREQHIGH ) | -VC4_SET_FIELD (0x10 ,VC4_HD_MAI_THR_DREQLOW )); +VC4_SET_FIELD (0x08 ,VC4_HD_MAI_THR_PANICHIGH ) | +VC4_SET_FIELD (0x08 ,VC4_HD_MAI_THR_PANICLOW ) | +VC4_SET_FIELD (0x06 ,VC4_HD_MAI_THR_DREQHIGH ) | +VC4_SET_FIELD (0x08 ,VC4_HD_MAI_THR_DREQLOW )); HDMI_WRITE(HDMI_MAI_CONFIG, VC4_HDMI_MAI_CONFIG_BIT_REVERSE |
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 307/779 drm/vc4: hdmi: Reset HDMI MISC_CONTROL register
In reply to Greg Kroah-HartmanFrom: Dave Stevenson <[email protected]>
[ Upstream commit 35dc00c12a72700a9c4592afee7d136ecb280cbd ]
The HDMI block can repeat pixels for double clocked modes, and the firmware is now configuring the block to do this as the PV is doing it incorrectly when at 2pixels/clock. If the kernel doesn't reset it then we end up with strange modes.
Reset MISC_CONTROL.
--- drivers/gpu/drm/vc4/vc4_hdmi.c | 8 ++++++++ drivers/gpu/drm/vc4/vc4_hdmi_regs.h | 3 +++ 2 files changed, 11 insertions(+)
drivers/gpu/drm/vc4/vc4_hdmi.c +8 -0
@@ -79,6 +79,9 @@#define VC5_HDMI_VERTB_VSPO_SHIFT 16#define VC5_HDMI_VERTB_VSPO_MASK VC4_MASK(29, 16) +#define VC5_HDMI_MISC_CONTROL_PIXEL_REP_SHIFT 0 +#define VC5_HDMI_MISC_CONTROL_PIXEL_REP_MASK VC4_MASK(3, 0) +#define VC5_HDMI_SCRAMBLER_CTL_ENABLE BIT(0)#define VC5_HDMI_DEEP_COLOR_CONFIG_1_INIT_PACK_PHASE_SHIFT 8
@@ -849,6 +852,11 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi, reg |= gcp_en ?VC5_HDMI_GCP_CONFIG_GCP_ENABLE :0 ;HDMI_WRITE (HDMI_GCP_CONFIG , reg); + reg =HDMI_READ (HDMI_MISC_CONTROL ); + reg &= ~VC5_HDMI_MISC_CONTROL_PIXEL_REP_MASK ; + reg |=VC4_SET_FIELD (0 ,VC5_HDMI_MISC_CONTROL_PIXEL_REP ); +HDMI_WRITE (HDMI_MISC_CONTROL , reg); +HDMI_WRITE (HDMI_CLOCK_STOP ,0 ); }
drivers/gpu/drm/vc4/vc4_hdmi_regs.h +3 -0
@@ -123,6 +123,7 @@ enum vc4_hdmi_field {HDMI_VERTB0 ,HDMI_VERTB1 ,HDMI_VID_CTL , + HDMI_MISC_CONTROL, }; struct vc4_hdmi_register {
@@ -233,6 +234,7 @@ static const struct vc4_hdmi_register __maybe_unused vc5_hdmi_hdmi0_fields[] = {VC4_HDMI_REG (HDMI_VERTB0 ,0x0f0 ),VC4_HDMI_REG (HDMI_VERTA1 ,0x0f4 ),VC4_HDMI_REG (HDMI_VERTB1 ,0x0f8 ), +VC4_HDMI_REG (HDMI_MISC_CONTROL ,0x100 ),VC4_HDMI_REG (HDMI_MAI_CHANNEL_MAP ,0x09c ),VC4_HDMI_REG (HDMI_MAI_CONFIG ,0x0a0 ), VC4_HDMI_REG(HDMI_DEEP_COLOR_CONFIG_1, 0x170),
@@ -313,6 +315,7 @@ static const struct vc4_hdmi_register __maybe_unused vc5_hdmi_hdmi1_fields[] = {VC4_HDMI_REG (HDMI_VERTB0 ,0x0f0 ),VC4_HDMI_REG (HDMI_VERTA1 ,0x0f4 ),VC4_HDMI_REG (HDMI_VERTB1 ,0x0f8 ), +VC4_HDMI_REG (HDMI_MISC_CONTROL ,0x100 ),VC4_HDMI_REG (HDMI_MAI_CHANNEL_MAP ,0x09c ),VC4_HDMI_REG (HDMI_MAI_CONFIG ,0x0a0 ), VC4_HDMI_REG(HDMI_DEEP_COLOR_CONFIG_1, 0x170),
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 308/779 drm/vc4: hdmi: Fix timings for interlaced modes
In reply to Greg Kroah-HartmanFrom: Mateusz Kwiatkowski <[email protected]>
[ Upstream commit 0ee5a40152b15f200ed3a0d51e8aa782ea979c6a ]
Increase the number of post-sync blanking lines on odd fields instead of decreasing it on even fields. This makes the total number of lines properly match the modelines.
Additionally fix the value of PV_VCONTROL_ODD_DELAY, which did not take pixels_per_clock into account, causing some displays to invert the fields when driven by bcm2711.
--- drivers/gpu/drm/vc4/vc4_crtc.c | 7 ++++--- drivers/gpu/drm/vc4/vc4_hdmi.c | 12 ++++++------ 2 files changed, 10 insertions(+), 9 deletions(-)
drivers/gpu/drm/vc4/vc4_crtc.c +4 -3
@@ -357,7 +357,8 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_atomic_state *s PV_HORZB_HACTIVE));CRTC_WRITE (PV_VERTA , -VC4_SET_FIELD (mode->crtc_vtotal - mode->crtc_vsync_end, +VC4_SET_FIELD (mode->crtc_vtotal - mode->crtc_vsync_end + + interlace,PV_VERTA_VBP ) |VC4_SET_FIELD (mode->crtc_vsync_end - mode->crtc_vsync_start,PV_VERTA_VSYNC ));
@@ -369,7 +370,7 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_atomic_state *s if (interlace) { CRTC_WRITE(PV_VERTA_EVEN, VC4_SET_FIELD(mode->crtc_vtotal - - mode->crtc_vsync_end - 1, + mode->crtc_vsync_end, PV_VERTA_VBP) | VC4_SET_FIELD(mode->crtc_vsync_end - mode->crtc_vsync_start,
@@ -389,7 +390,7 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_atomic_state *sPV_VCONTROL_CONTINUOUS | (is_dsi ?PV_VCONTROL_DSI :0 ) |PV_VCONTROL_INTERLACE | -VC4_SET_FIELD (mode->htotal * pixel_rep /2 , +VC4_SET_FIELD (mode->htotal * pixel_rep / (2 * ppc), PV_VCONTROL_ODD_DELAY));CRTC_WRITE (PV_VSYNCD_EVEN ,0 ); }else {
drivers/gpu/drm/vc4/vc4_hdmi.c +6 -6
@@ -738,12 +738,12 @@ static void vc4_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi, VC4_HDMI_VERTA_VFP) | VC4_SET_FIELD(mode->crtc_vdisplay, VC4_HDMI_VERTA_VAL));u32 vertb = (VC4_SET_FIELD (0 ,VC4_HDMI_VERTB_VSPO ) | -VC4_SET_FIELD (mode->crtc_vtotal - mode->crtc_vsync_end, +VC4_SET_FIELD (mode->crtc_vtotal - mode->crtc_vsync_end + + interlaced,VC4_HDMI_VERTB_VBP ));u32 vertb_even = (VC4_SET_FIELD (0 ,VC4_HDMI_VERTB_VSPO ) |VC4_SET_FIELD (mode->crtc_vtotal - - mode->crtc_vsync_end - - interlaced, + mode->crtc_vsync_end,VC4_HDMI_VERTB_VBP )); HDMI_WRITE(HDMI_HORZA,
@@ -784,12 +784,12 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi, VC5_HDMI_VERTA_VFP) | VC4_SET_FIELD(mode->crtc_vdisplay, VC5_HDMI_VERTA_VAL));u32 vertb = (VC4_SET_FIELD (0 ,VC5_HDMI_VERTB_VSPO ) | -VC4_SET_FIELD (mode->crtc_vtotal - mode->crtc_vsync_end, +VC4_SET_FIELD (mode->crtc_vtotal - mode->crtc_vsync_end + + interlaced,VC4_HDMI_VERTB_VBP ));u32 vertb_even = (VC4_SET_FIELD (0 ,VC5_HDMI_VERTB_VSPO ) |VC4_SET_FIELD (mode->crtc_vtotal - - mode->crtc_vsync_end - - interlaced, + mode->crtc_vsync_end,VC4_HDMI_VERTB_VBP ));unsigned char gcp;bool gcp_en;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 309/779 drm/vc4: hdmi: Correct HDMI timing registers for interlaced modes
In reply to Greg Kroah-HartmanFrom: Dave Stevenson <[email protected]>
[ Upstream commit fb10dc451c0f15e3c19798a2f41d357f3f7576f5 ]
For interlaced modes the timings were not being correctly programmed into the HDMI block, so correct them.
--- drivers/gpu/drm/vc4/vc4_hdmi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/gpu/drm/vc4/vc4_hdmi.c +4 -4
@@ -783,13 +783,13 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,VC4_SET_FIELD (mode->crtc_vsync_start - mode->crtc_vdisplay,VC5_HDMI_VERTA_VFP ) | VC4_SET_FIELD(mode->crtc_vdisplay, VC5_HDMI_VERTA_VAL)); -u32 vertb = (VC4_SET_FIELD (0 ,VC5_HDMI_VERTB_VSPO ) | -VC4_SET_FIELD (mode->crtc_vtotal - mode->crtc_vsync_end + - interlaced, +u32 vertb = (VC4_SET_FIELD (mode->htotal >> (2 - pixel_rep), +VC5_HDMI_VERTB_VSPO ) | +VC4_SET_FIELD (mode->crtc_vtotal - mode->crtc_vsync_end,VC4_HDMI_VERTB_VBP ));u32 vertb_even = (VC4_SET_FIELD (0 ,VC5_HDMI_VERTB_VSPO ) |VC4_SET_FIELD (mode->crtc_vtotal - - mode->crtc_vsync_end, + mode->crtc_vsync_end - interlaced,VC4_HDMI_VERTB_VBP ));unsigned char gcp;bool gcp_en;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 310/779 crypto: arm64/gcm - Select AEAD for GHASH_ARM64_CE
In reply to Greg Kroah-HartmanFrom: Qian Cai <[email protected]>
[ Upstream commit fac76f2260893dde5aa05bb693b4c13e8ed0454b ]
Otherwise, we could fail to compile.
ld: arch/arm64/crypto/ghash-ce-glue.o: in function 'ghash_ce_mod_exit':
ghash-ce-glue.c:(.exit.text+0x24): undefined reference to 'crypto_unregister_aead'
ld: arch/arm64/crypto/ghash-ce-glue.o: in function 'ghash_ce_mod_init':
ghash-ce-glue.c:(.init.text+0x34): undefined reference to 'crypto_register_aead'
--- arch/arm64/crypto/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/arm64/crypto/Kconfig +1 -0
@@ -59,6 +59,7 @@ config CRYPTO_GHASH_ARM64_CE select CRYPTO_HASH select CRYPTO_GF128MUL select CRYPTO_LIB_AES + select CRYPTO_AEAD config CRYPTO_CRCT10DIF_ARM64_CE tristate "CRCT10DIF digest algorithm using PMULL instructions"
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 311/779 selftests/xsk: Destroy BPF resources only when ctx refcount drops to 0
In reply to Greg Kroah-HartmanFrom: Maciej Fijalkowski <[email protected]>
[ Upstream commit 39e940d4abfabb08b6937a315546b24d10be67e3 ]
Currently, xsk_socket__delete frees BPF resources regardless of ctx refcount. Xdpxceiver has a test to verify whether underlying BPF resources would not be wiped out after closing XSK socket that was bound to interface with other active sockets. From library's xsk part perspective it also means that the internal xsk context is shared and its refcount is bumped accordingly.
After a switch to loading XDP prog based on previously opened XSK socket, mentioned xdpxceiver test fails with:
not ok 16 [xdpxceiver.c:swap_xsk_resources:1334]: ERROR: 9/"Bad file descriptor
which means that in swap_xsk_resources(), xsk_socket__delete() released xskmap which in turn caused a failure of xsk_socket__update_xskmap().
To fix this, when deleting socket, decrement ctx refcount before releasing BPF resources and do so only when refcount dropped to 0 which means there are no more active sockets for this ctx so BPF resources can be freed safely.
--- tools/lib/bpf/xsk.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
tools/lib/bpf/xsk.c +4 -5
@@ -1164,8 +1164,6 @@ int xsk_socket__create_shared(struct xsk_socket **xsk_ptr, goto out_mmap_tx; } - ctx->prog_fd =-1 ; -if (!(xsk->config.libbpf_flags &XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD )) { err =__xsk_setup_xdp_prog (xsk,NULL );if (err)
@@ -1246,7 +1244,10 @@ void xsk_socket__delete(struct xsk_socket *xsk) ctx = xsk->ctx; umem = ctx->umem; -if (ctx->prog_fd !=-1 ) { + +xsk_put_ctx (ctx, true); + +if (!ctx->refcount) {xsk_delete_bpf_maps (xsk);close (ctx->prog_fd);if (ctx->has_bpf_link)
@@ -1265,8 +1266,6 @@ void xsk_socket__delete(struct xsk_socket *xsk) } } -xsk_put_ctx (ctx, true); - umem->refcount--;/* Do not close an fd that also has an associated umem connected * to it.
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 312/779 drm/rockchip: vop: Dont crash for invalid duplicate_state()
In reply to Greg Kroah-HartmanFrom: Brian Norris <[email protected]>
[ Upstream commit 1449110b0dade8b638d2c17ab7c5b0ff696bfccb ]
It's possible for users to try to duplicate the CRTC state even when the state doesn't exist. drm_atomic_helper_crtc_duplicate_state() (and other users of __drm_atomic_helper_crtc_duplicate_state()) already guard this with a WARN_ON() instead of crashing, so let's do that here too.
--- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/rockchip/rockchip_drm_vop.c +3 -0
@@ -1550,6 +1550,9 @@ static struct drm_crtc_state *vop_crtc_duplicate_state(struct drm_crtc *crtc) {struct rockchip_crtc_state *rockchip_state; +if (WARN_ON (!crtc->state)) +return NULL ; + rockchip_state =kzalloc (sizeof (*rockchip_state),GFP_KERNEL );if (!rockchip_state)return NULL ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 313/779 drm/rockchip: Fix an error handling path rockchip_dp_probe()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 5074376822fe99fa4ce344b851c5016d00c0444f ]
Should component_add() fail, we should call analogix_dp_remove() in the error handling path, as already done in the remove function.
--- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +9 -1
@@ -398,7 +398,15 @@ static int rockchip_dp_probe(struct platform_device *pdev)if (IS_ERR (dp->adp))return PTR_ERR (dp->adp); -return component_add (dev, &rockchip_dp_component_ops); + ret =component_add (dev, &rockchip_dp_component_ops); +if (ret) + goto err_dp_remove; + +return 0 ; + +err_dp_remove: +analogix_dp_remove (dp->adp); +return ret; }static int rockchip_dp_remove (struct platform_device *pdev)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 314/779 drm/mediatek: dpi: Remove output format of YUV
In reply to Greg Kroah-HartmanFrom: Bo-Chen Chen <[email protected]>
[ Upstream commit c9ed0713b3c35fc45677707ba47f432cad95da56 ]
DPI is not support output format as YUV, but there is the setting of configuring output YUV. Therefore, remove them in this patch.
--- drivers/gpu/drm/mediatek/mtk_dpi.c | 31 ++++++------------------------ 1 file changed, 6 insertions(+), 25 deletions(-)
drivers/gpu/drm/mediatek/mtk_dpi.c +6 -25
@@ -54,13 +54,7 @@ enum mtk_dpi_out_channel_swap { };enum mtk_dpi_out_color_format { -MTK_DPI_COLOR_FORMAT_RGB , -MTK_DPI_COLOR_FORMAT_RGB_FULL , -MTK_DPI_COLOR_FORMAT_YCBCR_444 , -MTK_DPI_COLOR_FORMAT_YCBCR_422 , -MTK_DPI_COLOR_FORMAT_XV_YCC , -MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL , -MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL +MTK_DPI_COLOR_FORMAT_RGB };struct mtk_dpi {
@@ -364,24 +358,11 @@ static void mtk_dpi_config_disable_edge(struct mtk_dpi *dpi)static void mtk_dpi_config_color_format (struct mtk_dpi *dpi,enum mtk_dpi_out_color_format format) { -if ((format ==MTK_DPI_COLOR_FORMAT_YCBCR_444 ) || - (format ==MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL )) { -mtk_dpi_config_yuv422_enable (dpi, false); -mtk_dpi_config_csc_enable (dpi, true); -mtk_dpi_config_swap_input (dpi, false); -mtk_dpi_config_channel_swap (dpi,MTK_DPI_OUT_CHANNEL_SWAP_BGR ); - }else if ((format ==MTK_DPI_COLOR_FORMAT_YCBCR_422 ) || - (format ==MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL )) { -mtk_dpi_config_yuv422_enable (dpi, true); -mtk_dpi_config_csc_enable (dpi, true); -mtk_dpi_config_swap_input (dpi, true); -mtk_dpi_config_channel_swap (dpi,MTK_DPI_OUT_CHANNEL_SWAP_RGB ); - }else { -mtk_dpi_config_yuv422_enable (dpi, false); -mtk_dpi_config_csc_enable (dpi, false); -mtk_dpi_config_swap_input (dpi, false); -mtk_dpi_config_channel_swap (dpi,MTK_DPI_OUT_CHANNEL_SWAP_RGB ); - } +/* only support RGB888 */ +mtk_dpi_config_yuv422_enable (dpi, false); +mtk_dpi_config_csc_enable (dpi, false); +mtk_dpi_config_swap_input (dpi, false); +mtk_dpi_config_channel_swap (dpi,MTK_DPI_OUT_CHANNEL_SWAP_RGB ); }static void mtk_dpi_dual_edge (struct mtk_dpi *dpi)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 315/779 drm/mediatek: dpi: Only enable dpi after the bridge is enabled
In reply to Greg Kroah-HartmanFrom: Guillaume Ranquet <[email protected]>
[ Upstream commit aed61ef6beb911cc043af0f2f291167663995065 ]
Enabling the dpi too early causes glitches on screen.
Move the call to mtk_dpi_enable() at the end of the bridge_enable callback to ensure everything is setup properly before enabling dpi.
--- drivers/gpu/drm/mediatek/mtk_dpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/mediatek/mtk_dpi.c +1 -1
@@ -417,7 +417,6 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)if (dpi->pinctrl && dpi->pins_dpi)pinctrl_select_state (dpi->pinctrl, dpi->pins_dpi); -mtk_dpi_enable (dpi);return 0 ; err_pixel:
@@ -639,6 +638,7 @@ static void mtk_dpi_bridge_enable(struct drm_bridge *bridge)mtk_dpi_power_on (dpi);mtk_dpi_set_display_mode (dpi, &dpi->mode); +mtk_dpi_enable (dpi); } static enum drm_mode_status
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 316/779 drm: bridge: sii8620: fix possible off-by-one
In reply to Greg Kroah-HartmanFrom: Hangyu Hua <[email protected]>
[ Upstream commit 21779cc21c732c5eff8ea1624be6590450baa30f ]
The next call to sii8620_burst_get_tx_buf will result in off-by-one When ctx->burst.tx_count + size == ARRAY_SIZE(ctx->burst.tx_buf). The same thing happens in sii8620_burst_get_rx_buf.
This patch also change tx_count and tx_buf to rx_count and rx_buf in sii8620_burst_get_rx_buf. It is unreasonable to check tx_buf's size and use rx_buf.
--- drivers/gpu/drm/bridge/sil-sii8620.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/bridge/sil-sii8620.c +2 -2
@@ -605,7 +605,7 @@ static void *sii8620_burst_get_tx_buf(struct sii8620 *ctx, int len)u8 *buf = &ctx->burst.tx_buf[ctx->burst.tx_count];int size = len +2 ; -if (ctx->burst.tx_count + size >ARRAY_SIZE (ctx->burst.tx_buf)) { +if (ctx->burst.tx_count + size >=ARRAY_SIZE (ctx->burst.tx_buf)) {dev_err (ctx->dev,"TX-BLK buffer exhausted\n" ); ctx->error = -EINVAL ;return NULL ;
@@ -622,7 +622,7 @@ static u8 *sii8620_burst_get_rx_buf(struct sii8620 *ctx, int len)u8 *buf = &ctx->burst.rx_buf[ctx->burst.rx_count];int size = len +1 ; -if (ctx->burst.tx_count + size >ARRAY_SIZE (ctx->burst.tx_buf)) { +if (ctx->burst.rx_count + size >=ARRAY_SIZE (ctx->burst.rx_buf)) {dev_err (ctx->dev,"RX-BLK buffer exhausted\n" ); ctx->error = -EINVAL ;return NULL ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 317/779 hinic: Use the bitmap API when applicable
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 7c2c57263af41cfd8b5022274e6801542831bb69 ]
'vlan_bitmap' is a bitmap and is used as such. So allocate it with devm_bitmap_zalloc() and its explicit bit size (i.e. VLAN_N_VID).
This avoids the need of the VLAN_BITMAP_SIZE macro which:
- needlessly has a 'nic_dev' parameter
- should be "long" (and not byte) aligned, so that the bitmap semantic is respected
This is in fact not an issue because VLAN_N_VID is 4096 at the time being, but devm_bitmap_zalloc() is less verbose and easier to understand.
--- drivers/net/ethernet/huawei/hinic/hinic_main.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
drivers/net/ethernet/huawei/hinic/hinic_main.c +2 -5
@@ -62,8 +62,6 @@ MODULE_PARM_DESC(rx_weight, "Number Rx packets for NAPI budget (default=64)");#define HINIC_LRO_RX_TIMER_DEFAULT 16 -#define VLAN_BITMAP_SIZE (nic_dev) (ALIGN(VLAN_N_VID, 8) / 8) -#define work_to_rx_mode_work (work) \ container_of(work, struct hinic_rx_mode_work, work)
@@ -1241,9 +1239,8 @@ static int nic_dev_init(struct pci_dev *pdev)u64_stats_init (&tx_stats->syncp);u64_stats_init (&rx_stats->syncp); - nic_dev->vlan_bitmap =devm_kzalloc (&pdev->dev, -VLAN_BITMAP_SIZE (nic_dev), -GFP_KERNEL ); + nic_dev->vlan_bitmap =devm_bitmap_zalloc (&pdev->dev,VLAN_N_VID , +GFP_KERNEL );if (!nic_dev->vlan_bitmap) { err = -ENOMEM ; goto err_vlan_bitmap;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 318/779 net: hinic: fix bug that ethtool get wrong stats
In reply to Greg Kroah-HartmanFrom: Qiao Ma <[email protected]>
[ Upstream commit 67dffd3db98570af8ff54c934f7d14664c0d182a ]
Function hinic_get_stats64() will do two operations:
1. reads stats from every hinic_rxq/txq and accumulates them
2. calls hinic_rxq/txq_clean_stats() to clean every rxq/txq's stats
For hinic_get_stats64(), it could get right data, because it sums all data to nic_dev->rx_stats/tx_stats.
But it is wrong for get_drv_queue_stats(), this function will read hinic_rxq's stats, which have been cleared to zero by hinic_get_stats64().
I have observed hinic's cleanup operation by using such command:
Quoted 1 line
watch -n 1 "cat ethtool -S eth4 | tail -40"
Result before:
...
rxq7_pkts: 1
rxq7_bytes: 90
rxq7_errors: 0
rxq7_csum_errors: 0
rxq7_other_errors: 0
...
rxq9_pkts: 11
rxq9_bytes: 726
rxq9_errors: 0
rxq9_csum_errors: 0
rxq9_other_errors: 0
...
rxq11_pkts: 0
rxq11_bytes: 0
rxq11_errors: 0
rxq11_csum_errors: 0
rxq11_other_errors: 0Result after a few seconds:
...
rxq7_pkts: 0
rxq7_bytes: 0
rxq7_errors: 0
rxq7_csum_errors: 0
rxq7_other_errors: 0
...
rxq9_pkts: 2
rxq9_bytes: 132
rxq9_errors: 0
rxq9_csum_errors: 0
rxq9_other_errors: 0
...
rxq11_pkts: 1
rxq11_bytes: 170
rxq11_errors: 0
rxq11_csum_errors: 0
rxq11_other_errors: 0To solve this problem, we just keep every queue's total stats in their own queue (aka hinic_{rxq|txq}), and simply sum all per-queue stats every time calling hinic_get_stats64().
With that solution, there is no need to clean per-queue stats now, and there is no need to maintain global hinic_dev.{tx|rx}_stats, too.
--- drivers/net/ethernet/huawei/hinic/hinic_dev.h | 3 - .../net/ethernet/huawei/hinic/hinic_main.c | 57 ++++++------------- drivers/net/ethernet/huawei/hinic/hinic_rx.c | 2 - drivers/net/ethernet/huawei/hinic/hinic_tx.c | 2 - 4 files changed, 16 insertions(+), 48 deletions(-)
drivers/net/ethernet/huawei/hinic/hinic_dev.h +0 -3
@@ -95,9 +95,6 @@ struct hinic_dev {u16 sq_depth;u16 rq_depth; -struct hinic_txq_stats tx_stats; -struct hinic_rxq_stats rx_stats; -u8 rss_tmpl_idx;u8 rss_hash_engine;u16 num_rss;
drivers/net/ethernet/huawei/hinic/hinic_main.c +16 -41
126 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_rx.c +0 -2
@@ -73,7 +73,6 @@ void hinic_rxq_get_stats(struct hinic_rxq *rxq, struct hinic_rxq_stats *stats)struct hinic_rxq_stats *rxq_stats = &rxq->rxq_stats;unsigned int start; -u64_stats_update_begin (&stats->syncp); do { start = u64_stats_fetch_begin(&rxq_stats->syncp); stats->pkts = rxq_stats->pkts;
@@ -83,7 +82,6 @@ void hinic_rxq_get_stats(struct hinic_rxq *rxq, struct hinic_rxq_stats *stats) stats->csum_errors = rxq_stats->csum_errors; stats->other_errors = rxq_stats->other_errors; }while (u64_stats_fetch_retry (&rxq_stats->syncp, start)); -u64_stats_update_end (&stats->syncp); }/**
drivers/net/ethernet/huawei/hinic/hinic_tx.c +0 -2
@@ -97,7 +97,6 @@ void hinic_txq_get_stats(struct hinic_txq *txq, struct hinic_txq_stats *stats)struct hinic_txq_stats *txq_stats = &txq->txq_stats;unsigned int start; -u64_stats_update_begin (&stats->syncp); do { start = u64_stats_fetch_begin(&txq_stats->syncp); stats->pkts = txq_stats->pkts;
@@ -107,7 +106,6 @@ void hinic_txq_get_stats(struct hinic_txq *txq, struct hinic_txq_stats *stats) stats->tx_dropped = txq_stats->tx_dropped; stats->big_frags_pkts = txq_stats->big_frags_pkts; }while (u64_stats_fetch_retry (&txq_stats->syncp, start)); -u64_stats_update_end (&stats->syncp); }/**
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 319/779 net: hinic: avoid kernel hung in hinic_get_stats64()
In reply to Greg Kroah-HartmanFrom: Qiao Ma <[email protected]>
[ Upstream commit 98f9fcdee35add80505b6c73f72de5f750d5c03c ]
When using hinic device as a bond slave device, and reading device stats of master bond device, the kernel may hung.
The kernel panic calltrace as follows:
Kernel panic - not syncing: softlockup: hung tasks Call trace: native_queued_spin_lock_slowpath+0x1ec/0x31c dev_get_stats+0x60/0xcc dev_seq_printf_stats+0x40/0x120 dev_seq_show+0x1c/0x40 seq_read_iter+0x3c8/0x4dc seq_read+0xe0/0x130 proc_reg_read+0xa8/0xe0 vfs_read+0xb0/0x1d4 ksys_read+0x70/0xfc __arm64_sys_read+0x20/0x30 el0_svc_common+0x88/0x234 do_el0_svc+0x2c/0x90 el0_svc+0x1c/0x30 el0_sync_handler+0xa8/0xb0 el0_sync+0x148/0x180
And the calltrace of task that actually caused kernel hungs as follows:
__switch_to+124
__schedule+548
schedule+72
schedule_timeout+348
__down_common+188
__down+24
down+104
hinic_get_stats64+44 [hinic]
dev_get_stats+92
bond_get_stats+172 [bonding]
dev_get_stats+92
dev_seq_printf_stats+60
dev_seq_show+24
seq_read_iter+964
seq_read+220
proc_reg_read+164
vfs_read+172
ksys_read+108
__arm64_sys_read+28
el0_svc_common+132
do_el0_svc+40
el0_svc+24
el0_sync_handler+164
el0_sync+324
When getting device stats from bond, kernel will call bond_get_stats(). It first holds the spinlock bond->stats_lock, and then call hinic_get_stats64() to collect hinic device's stats. However, hinic_get_stats64() calls down(&nic_dev->mgmt_lock) to protect its critical section, which may schedule current task out. And if system is under high pressure, the task cannot be woken up immediately, which eventually triggers kernel hung panic.
Since previous patch has replaced hinic_dev.tx_stats/rx_stats with local variable in hinic_get_stats64(), there is nothing need to be protected by lock, so just removing down()/up() is ok.
--- drivers/net/ethernet/huawei/hinic/hinic_main.c | 4 ---- 1 file changed, 4 deletions(-)
drivers/net/ethernet/huawei/hinic/hinic_main.c +0 -4
@@ -842,13 +842,9 @@ static void hinic_get_stats64(struct net_device *netdev,struct hinic_rxq_stats nic_rx_stats = {};struct hinic_txq_stats nic_tx_stats = {}; -down (&nic_dev->mgmt_lock); -if (nic_dev->flags &HINIC_INTF_UP )gather_nic_stats (nic_dev, &nic_rx_stats, &nic_tx_stats); -up (&nic_dev->mgmt_lock); - stats->rx_bytes = nic_rx_stats.bytes; stats->rx_packets = nic_rx_stats.pkts; stats->rx_errors = nic_rx_stats.errors;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 320/779 drm/msm/mdp5: Fix global state lock backoff
In reply to Greg Kroah-HartmanFrom: Rob Clark <[email protected]>
[ Upstream commit 92ef86ab513593c6329d04146e61f9a670e72fc5 ]
We need to grab the lock after the early return for !hwpipe case. Otherwise, we could have hit contention yet still returned 0.
Fixes an issue that the new CONFIG_DRM_DEBUG_MODESET_LOCK stuff flagged in CI:
WARNING: CPU: 0 PID: 282 at drivers/gpu/drm/drm_modeset_lock.c:296 drm_modeset_lock+0xf8/0x154
Modules linked in:
CPU: 0 PID: 282 Comm: kms_cursor_lega Tainted: G W 5.19.0-rc2-15930-g875cc8bc536a #1
Hardware name: Qualcomm Technologies, Inc. DB820c (DT)
pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : drm_modeset_lock+0xf8/0x154
lr : drm_atomic_get_private_obj_state+0x84/0x170
sp : ffff80000cfab6a0
x29: ffff80000cfab6a0 x28: 0000000000000000 x27: ffff000083bc4d00
x26: 0000000000000038 x25: 0000000000000000 x24: ffff80000957ca58
x23: 0000000000000000 x22: ffff000081ace080 x21: 0000000000000001
x20: ffff000081acec18 x19: ffff80000cfabb80 x18: 0000000000000038
x17: 0000000000000000 x16: 0000000000000000 x15: fffffffffffea0d0
x14: 0000000000000000 x13: 284e4f5f4e524157 x12: 5f534b434f4c5f47
x11: ffff80000a386aa8 x10: 0000000000000029 x9 : ffff80000cfab610
x8 : 0000000000000029 x7 : 0000000000000014 x6 : 0000000000000000
x5 : 0000000000000001 x4 : ffff8000081ad904 x3 : 0000000000000029
x2 : ffff0000801db4c0 x1 : ffff80000cfabb80 x0 : ffff000081aceb58
Call trace:
drm_modeset_lock+0xf8/0x154
drm_atomic_get_private_obj_state+0x84/0x170
mdp5_get_global_state+0x54/0x6c
mdp5_pipe_release+0x2c/0xd4
mdp5_plane_atomic_check+0x2ec/0x414
drm_atomic_helper_check_planes+0xd8/0x210
drm_atomic_helper_check+0x54/0xb0
...
---[ end trace 0000000000000000 ]---
drm_modeset_lock attempting to lock a contended lock without backoff:
drm_modeset_lock+0x148/0x154
mdp5_get_global_state+0x30/0x6c
mdp5_pipe_release+0x2c/0xd4
mdp5_plane_atomic_check+0x290/0x414
drm_atomic_helper_check_planes+0xd8/0x210
drm_atomic_helper_check+0x54/0xb0
drm_atomic_check_only+0x4b0/0x8f4
drm_atomic_commit+0x68/0xe0Patchwork: https://patchwork.freedesktop.org/patch/492701/
--- drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c +2 -1
@@ -123,12 +123,13 @@ int mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe) {struct msm_drm_private *priv = s->dev->dev_private;struct mdp5_kms *mdp5_kms =to_mdp5_kms (to_mdp_kms (priv->kms)); -struct mdp5_global_state *state =mdp5_get_global_state (s); +struct mdp5_global_state *state;struct mdp5_hw_pipe_state *new_state;if (!hwpipe)return 0 ; + state =mdp5_get_global_state (s);if (IS_ERR (state))return PTR_ERR (state);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 321/779 crypto: hisilicon/sec - dont sleep when in softirq
In reply to Greg Kroah-HartmanFrom: Zhengchao Shao <[email protected]>
[ Upstream commit 02884a4f12de11f54d4ca67a07dd1f111d96fdbd ]
When kunpeng920 encryption driver is used to deencrypt and decrypt packets during the softirq, it is not allowed to use mutex lock. The kernel will report the following error:
BUG: scheduling while atomic: swapper/57/0/0x00000300 Call trace: dump_backtrace+0x0/0x1e4 show_stack+0x20/0x2c dump_stack+0xd8/0x140 __schedule_bug+0x68/0x80 __schedule+0x728/0x840 schedule+0x50/0xe0 schedule_preempt_disabled+0x18/0x24 __mutex_lock.constprop.0+0x594/0x5dc __mutex_lock_slowpath+0x1c/0x30 mutex_lock+0x50/0x60 sec_request_init+0x8c/0x1a0 [hisi_sec2] sec_process+0x28/0x1ac [hisi_sec2] sec_skcipher_crypto+0xf4/0x1d4 [hisi_sec2] sec_skcipher_encrypt+0x1c/0x30 [hisi_sec2] crypto_skcipher_encrypt+0x2c/0x40 crypto_authenc_encrypt+0xc8/0xfc [authenc] crypto_aead_encrypt+0x2c/0x40 echainiv_encrypt+0x144/0x1a0 [echainiv] crypto_aead_encrypt+0x2c/0x40 esp_output_tail+0x348/0x5c0 [esp4] esp_output+0x120/0x19c [esp4] xfrm_output_one+0x25c/0x4d4 xfrm_output_resume+0x6c/0x1fc xfrm_output+0xac/0x3c0 xfrm4_output+0x64/0x130 ip_build_and_send_pkt+0x158/0x20c tcp_v4_send_synack+0xdc/0x1f0 tcp_conn_request+0x7d0/0x994 tcp_v4_conn_request+0x58/0x6c tcp_v6_conn_request+0xf0/0x100 tcp_rcv_state_process+0x1cc/0xd60 tcp_v4_do_rcv+0x10c/0x250 tcp_v4_rcv+0xfc4/0x10a4 ip_protocol_deliver_rcu+0xf4/0x200 ip_local_deliver_finish+0x58/0x70 ip_local_deliver+0x68/0x120 ip_sublist_rcv_finish+0x70/0x94 ip_list_rcv_finish.constprop.0+0x17c/0x1d0 ip_sublist_rcv+0x40/0xb0 ip_list_rcv+0x140/0x1dc __netif_receive_skb_list_core+0x154/0x28c __netif_receive_skb_list+0x120/0x1a0 netif_receive_skb_list_internal+0xe4/0x1f0 napi_complete_done+0x70/0x1f0 gro_cell_poll+0x9c/0xb0 napi_poll+0xcc/0x264 net_rx_action+0xd4/0x21c __do_softirq+0x130/0x358 irq_exit+0x11c/0x13c __handle_domain_irq+0x88/0xf0 gic_handle_irq+0x78/0x2c0 el1_irq+0xb8/0x140 arch_cpu_idle+0x18/0x40 default_idle_call+0x5c/0x1c0 cpuidle_idle_call+0x174/0x1b0 do_idle+0xc8/0x160 cpu_startup_entry+0x30/0x11c secondary_start_kernel+0x158/0x1e4
softirq: huh, entered softirq 3 NET_RX 0000000093774ee4 with preempt_count 00000100, exited with fffffe00?
--- drivers/crypto/hisilicon/sec2/sec.h | 2 +- drivers/crypto/hisilicon/sec2/sec_crypto.c | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-)
drivers/crypto/hisilicon/sec2/sec.h +1 -1
@@ -119,7 +119,7 @@ struct sec_qp_ctx {struct idr req_idr;struct sec_alg_res res[QM_Q_DEPTH ];struct sec_ctx *ctx; -struct mutex req_lock; +spinlock_t req_lock;struct list_head backlog;struct hisi_acc_sgl_pool *c_in_pool;struct hisi_acc_sgl_pool *c_out_pool;
drivers/crypto/hisilicon/sec2/sec_crypto.c +10 -10
@@ -124,11 +124,11 @@ static int sec_alloc_req_id(struct sec_req *req, struct sec_qp_ctx *qp_ctx) {int req_id; -mutex_lock (&qp_ctx->req_lock); +spin_lock_bh (&qp_ctx->req_lock); req_id =idr_alloc_cyclic (&qp_ctx->req_idr,NULL ,0 ,QM_Q_DEPTH ,GFP_ATOMIC ); -mutex_unlock (&qp_ctx->req_lock); +spin_unlock_bh (&qp_ctx->req_lock);if (unlikely (req_id <0 )) {dev_err (req->ctx->dev,"alloc req id fail!\n" );return req_id;
@@ -153,9 +153,9 @@ static void sec_free_req_id(struct sec_req *req) qp_ctx->req_list[req_id] =NULL ; req->qp_ctx =NULL ; -mutex_lock (&qp_ctx->req_lock); +spin_lock_bh (&qp_ctx->req_lock);idr_remove (&qp_ctx->req_idr, req_id); -mutex_unlock (&qp_ctx->req_lock); +spin_unlock_bh (&qp_ctx->req_lock); }static u8 pre_parse_finished_bd (struct bd_status *status,void *resp)
@@ -270,7 +270,7 @@ static int sec_bd_send(struct sec_ctx *ctx, struct sec_req *req) !(req->flag & CRYPTO_TFM_REQ_MAY_BACKLOG))return -EBUSY ; -mutex_lock (&qp_ctx->req_lock); +spin_lock_bh (&qp_ctx->req_lock); ret =hisi_qp_send (qp_ctx->qp, &req->sec_sqe); if (ctx->fake_req_limit <=
@@ -278,10 +278,10 @@ static int sec_bd_send(struct sec_ctx *ctx, struct sec_req *req)list_add_tail (&req->backlog_head, &qp_ctx->backlog);atomic64_inc (&ctx->sec->debug.dfx.send_cnt);atomic64_inc (&ctx->sec->debug.dfx.send_busy_cnt); -mutex_unlock (&qp_ctx->req_lock); +spin_unlock_bh (&qp_ctx->req_lock);return -EBUSY ; } -mutex_unlock (&qp_ctx->req_lock); +spin_unlock_bh (&qp_ctx->req_lock);if (unlikely (ret == -EBUSY ))return -ENOBUFS ;
@@ -484,7 +484,7 @@ static int sec_create_qp_ctx(struct hisi_qm *qm, struct sec_ctx *ctx, qp->req_cb = sec_req_cb; -mutex_init (&qp_ctx->req_lock); +spin_lock_init (&qp_ctx->req_lock);idr_init (&qp_ctx->req_idr);INIT_LIST_HEAD (&qp_ctx->backlog);
@@ -1373,7 +1373,7 @@ static struct sec_req *sec_back_req_clear(struct sec_ctx *ctx, {struct sec_req *backlog_req =NULL ; -mutex_lock (&qp_ctx->req_lock); +spin_lock_bh (&qp_ctx->req_lock);if (ctx->fake_req_limit >=atomic_read (&qp_ctx->qp->qp_status.used) && !list_empty (&qp_ctx->backlog)) {
@@ -1381,7 +1381,7 @@ static struct sec_req *sec_back_req_clear(struct sec_ctx *ctx, typeof(*backlog_req), backlog_head);list_del (&backlog_req->backlog_head); } -mutex_unlock (&qp_ctx->req_lock); +spin_unlock_bh (&qp_ctx->req_lock);return backlog_req; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 322/779 crypto: hisilicon - Kunpeng916 crypto driver dont sleep when in softirq
In reply to Greg Kroah-HartmanFrom: Zhengchao Shao <[email protected]>
[ Upstream commit 68740ab505431f268dc1ee26a54b871e75f0ddaa ]
When kunpeng916 encryption driver is used to deencrypt and decrypt packets during the softirq, it is not allowed to use mutex lock.
--- drivers/crypto/hisilicon/sec/sec_algs.c | 14 +++++++------- drivers/crypto/hisilicon/sec/sec_drv.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-)
drivers/crypto/hisilicon/sec/sec_algs.c +7 -7
@@ -449,7 +449,7 @@ static void sec_skcipher_alg_callback(struct sec_bd_info *sec_resp,*/ } -mutex_lock (&ctx->queue->queuelock); +spin_lock_bh (&ctx->queue->queuelock);/* Put the IV in place for chained cases */ switch (ctx->cipher_alg) {case SEC_C_AES_CBC_128 :
@@ -509,7 +509,7 @@ static void sec_skcipher_alg_callback(struct sec_bd_info *sec_resp,list_del (&backlog_req->backlog_head); } } -mutex_unlock (&ctx->queue->queuelock); +spin_unlock_bh (&ctx->queue->queuelock);mutex_lock (&sec_req->lock);list_del (&sec_req_el->head);
@@ -798,7 +798,7 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,*/ /* Grab a big lock for a long time to avoid concurrency issues */ -mutex_lock (&queue->queuelock); +spin_lock_bh (&queue->queuelock);/* * Can go on to queue if we have space in either:
@@ -814,15 +814,15 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq, ret = -EBUSY ;if ((skreq->base.flags &CRYPTO_TFM_REQ_MAY_BACKLOG )) {list_add_tail (&sec_req->backlog_head, &ctx->backlog); -mutex_unlock (&queue->queuelock); +spin_unlock_bh (&queue->queuelock); goto out; } -mutex_unlock (&queue->queuelock); +spin_unlock_bh (&queue->queuelock); goto err_free_elements; } ret =sec_send_request (sec_req, queue); -mutex_unlock (&queue->queuelock); +spin_unlock_bh (&queue->queuelock);if (ret) goto err_free_elements;
@@ -881,7 +881,7 @@ static int sec_alg_skcipher_init(struct crypto_skcipher *tfm)if (IS_ERR (ctx->queue))return PTR_ERR (ctx->queue); -mutex_init (&ctx->queue->queuelock); +spin_lock_init (&ctx->queue->queuelock); ctx->queue->havesoftqueue = false;return 0 ;
drivers/crypto/hisilicon/sec/sec_drv.h +1 -1
@@ -347,7 +347,7 @@ struct sec_queue {DECLARE_BITMAP (unprocessed,SEC_QUEUE_LEN ); DECLARE_KFIFO_PTR(softqueue, typeof(struct sec_request_el *));bool havesoftqueue; -struct mutex queuelock; +spinlock_t queuelock;void *shadow[SEC_QUEUE_LEN ]; };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 323/779 media: platform: mtk-mdp: Fix mdp_ipi_comm structure alignment
In reply to Greg Kroah-HartmanFrom: AngeloGioacchino Del Regno <[email protected]>
[ Upstream commit ab14c99c035da7156a3b66fa171171295bc4b89a ]
The mdp_ipi_comm structure defines a command that is either PROCESS (start processing) or DEINIT (destroy instance); we are using this one to send PROCESS or DEINIT commands from Linux to an MDP instance through a VPU write but, while the first wants us to stay 4-bytes aligned, the VPU instead requires an 8-bytes data alignment.
Keeping in mind that these commands are executed immediately after sending them (hence not chained with others before the VPU/MDP "actually" start executing), it is fine to simply add a padding of 4 bytes to this structure: this keeps the same performance as before, as we're still stack-allocating it, while avoiding hackery inside of mtk-vpu to ensure alignment bringing a definitely bigger performance impact.
--- drivers/media/platform/mtk-mdp/mtk_mdp_ipi.h | 2 ++ 1 file changed, 2 insertions(+)
drivers/media/platform/mtk-mdp/mtk_mdp_ipi.h +2 -0
@@ -40,12 +40,14 @@ struct mdp_ipi_init {* @ipi_id : IPI_MDP * @ap_inst : AP mtk_mdp_vpu address * @vpu_inst_addr : VPU MDP instance address +* @padding : Alignment padding */ struct mdp_ipi_comm {uint32_t msg_id;uint32_t ipi_id;uint64_t ap_inst;uint32_t vpu_inst_addr; +uint32_t padding; };/**
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 324/779 drm/msm: Avoid dirtyfb stalls on video mode displays (v2)
In reply to Greg Kroah-HartmanFrom: Rob Clark <[email protected]>
[ Upstream commit 9e4dde28e9cd34ee13a6b7247f0857fb49fd3f19 ]
Someone on IRC once asked an innocent enough sounding question: Why with xf86-video-modesetting is es2gears limited at 120fps.
So I broke out the perfetto tracing mesa MR and took a look. It turns out the problem was drm_atomic_helper_dirtyfb(), which would end up waiting for vblank.. es2gears would rapidly push two frames to Xorg, which would blit them to screen and in idle hook (I assume) call the DIRTYFB ioctl. Which in turn would do an atomic update to flush the dirty rects, which would stall until the next vblank. And then the whole process would repeat.
But this is a bit silly, we only need dirtyfb for command mode DSI panels. So track in plane state whether dirtyfb is required, and track in the fb how many attached planes require dirtyfb so that we can skip it when not required. (Note, mdp4 does not actually have cmd mode support.)
--- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 20 ++++++++++- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 5 +-- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 3 ++ drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c | 19 ++++++++-- drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 8 +++++ drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h | 5 +++ drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 21 +++++++++-- drivers/gpu/drm/msm/msm_atomic.c | 15 -------- drivers/gpu/drm/msm/msm_drv.h | 6 ++-- drivers/gpu/drm/msm/msm_fb.c | 41 ++++++++++++++++++---- 10 files changed, 110 insertions(+), 33 deletions(-)
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +19 -1
@@ -898,6 +898,20 @@ struct plane_state {u32 pipe_id; }; +static bool dpu_crtc_needs_dirtyfb (struct drm_crtc_state *cstate) +{ +struct drm_crtc *crtc = cstate->crtc; +struct drm_encoder *encoder; + + drm_for_each_encoder_mask (encoder, crtc->dev, cstate->encoder_mask) { +if (dpu_encoder_get_intf_mode (encoder) ==INTF_MODE_CMD ) { +return true; + } + } + +return false; +} +static int dpu_crtc_atomic_check (struct drm_crtc *crtc,struct drm_atomic_state *state) {
@@ -918,6 +932,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,const struct drm_plane_state *pipe_staged[SSPP_MAX ];int left_zpos_cnt =0 , right_zpos_cnt =0 ;struct drm_rect crtc_rect = {0 }; +bool needs_dirtyfb =dpu_crtc_needs_dirtyfb (crtc_state); pstates =kzalloc (sizeof (*pstates) *DPU_STAGE_MAX *4 ,GFP_KERNEL );
@@ -949,6 +964,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,/* get plane state for all drm planes associated with crtc state */ drm_atomic_crtc_state_for_each_plane_state (plane, pstate, crtc_state) { +struct dpu_plane_state *dpu_pstate =to_dpu_plane_state (pstate);struct drm_rect dst, clip = crtc_rect;if (IS_ERR_OR_NULL (pstate)) {
@@ -960,11 +976,13 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,if (cnt >=DPU_STAGE_MAX *4 )continue ; - pstates[cnt].dpu_pstate =to_dpu_plane_state (pstate); + pstates[cnt].dpu_pstate = dpu_pstate; pstates[cnt].drm_pstate = pstate; pstates[cnt].stage = pstate->normalized_zpos; pstates[cnt].pipe_id =dpu_plane_pipe (plane); + dpu_pstate->needs_dirtyfb = needs_dirtyfb; +if (pipe_staged[pstates[cnt].pipe_id]) { multirect_plane[multirect_count].r0 = pipe_staged[pstates[cnt].pipe_id];
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +3 -2
@@ -894,7 +894,7 @@ static int dpu_plane_prepare_fb(struct drm_plane *plane,if (pstate->aspace) { ret =msm_framebuffer_prepare (new_state->fb, - pstate->aspace); + pstate->aspace, pstate->needs_dirtyfb);if (ret) {DPU_ERROR ("failed to prepare framebuffer\n" );return ret;
@@ -925,7 +925,8 @@ static void dpu_plane_cleanup_fb(struct drm_plane *plane,DPU_DEBUG_PLANE (pdpu,"FB[%u]\n" , old_state->fb->base.id); -msm_framebuffer_cleanup (old_state->fb, old_pstate->aspace); +msm_framebuffer_cleanup (old_state->fb, old_pstate->aspace, + old_pstate->needs_dirtyfb); } static bool dpu_plane_validate_src(struct drm_rect *src,
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h +3 -0
@@ -28,6 +28,7 @@* @cdp_cfg: CDP configuration * @plane_fetch_bw: calculated BW per plane * @plane_clk: calculated clk per plane +* @needs_dirtyfb: whether attached CRTC needs pixel data explicitly flushed */ struct dpu_plane_state {struct drm_plane_state base;
@@ -45,6 +46,8 @@ struct dpu_plane_state {struct dpu_hw_pipe_cdp_cfg cdp_cfg;u64 plane_fetch_bw;u64 plane_clk; + +bool needs_dirtyfb; };/**
drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c +17 -2
@@ -7,6 +7,7 @@#include <drm/drm_atomic.h> #include <drm/drm_damage_helper.h> #include <drm/drm_fourcc.h> +#include <drm/drm_gem_atomic_helper.h> #include "mdp4_kms.h"
@@ -90,6 +91,20 @@ static const struct drm_plane_funcs mdp4_plane_funcs = { .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, }; +static int mdp4_plane_prepare_fb (struct drm_plane *plane, +struct drm_plane_state *new_state) +{ +struct msm_drm_private *priv = plane->dev->dev_private; +struct msm_kms *kms = priv->kms; + +if (!new_state->fb) +return 0 ; + +drm_gem_plane_helper_prepare_fb (plane, new_state); + +return msm_framebuffer_prepare (new_state->fb, kms->aspace, false); +} +static void mdp4_plane_cleanup_fb (struct drm_plane *plane,struct drm_plane_state *old_state) {
@@ -102,7 +117,7 @@ static void mdp4_plane_cleanup_fb(struct drm_plane *plane,return ;DBG ("%s: cleanup: FB[%u]" , mdp4_plane->name, fb->base.id); -msm_framebuffer_cleanup (fb, kms->aspace); +msm_framebuffer_cleanup (fb, kms->aspace, false); }
@@ -130,7 +145,7 @@ static void mdp4_plane_atomic_update(struct drm_plane *plane, }static const struct drm_plane_helper_funcs mdp4_plane_helper_funcs = { - .prepare_fb = msm_atomic_prepare_fb, + .prepare_fb = mdp4_plane_prepare_fb, .cleanup_fb = mdp4_plane_cleanup_fb, .atomic_check = mdp4_plane_atomic_check, .atomic_update = mdp4_plane_atomic_update,
drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +8 -0
@@ -696,6 +696,8 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc, {struct drm_crtc_state *crtc_state =drm_atomic_get_new_crtc_state (state, crtc); +struct mdp5_crtc_state *mdp5_cstate =to_mdp5_crtc_state (crtc_state); +struct mdp5_interface *intf = mdp5_cstate->pipeline.intf;struct mdp5_kms *mdp5_kms =get_kms (crtc);struct drm_plane *plane;struct drm_device *dev = crtc->dev;
@@ -712,12 +714,18 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc,DBG ("%s: check" , crtc->name);drm_atomic_crtc_state_for_each_plane_state (plane, pstate, crtc_state) { +struct mdp5_plane_state *mdp5_pstate = +to_mdp5_plane_state (pstate); +if (!pstate->visible)continue ; pstates[cnt].plane = plane; pstates[cnt].state =to_mdp5_plane_state (pstate); + mdp5_pstate->needs_dirtyfb = + intf->mode ==MDP5_INTF_DSI_MODE_COMMAND ; +/* * if any plane on this crtc uses 2 hwpipes, then we need * the crtc to have a right hwmixer.
drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h +5 -0
@@ -100,6 +100,11 @@ struct mdp5_plane_state {/* assigned by crtc blender */ enum mdp_mixer_stage_id stage; + +/* whether attached CRTC needs pixel data explicitly flushed to +* display (ex. DSI command mode display) +*/ +bool needs_dirtyfb; };#define to_mdp5_plane_state (x) \ container_of(x, struct mdp5_plane_state, base)
drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c +19 -2
@@ -8,6 +8,7 @@#include <drm/drm_atomic.h> #include <drm/drm_damage_helper.h> #include <drm/drm_fourcc.h> +#include <drm/drm_gem_atomic_helper.h> #include <drm/drm_print.h> #include "mdp5_kms.h"
@@ -143,18 +144,34 @@ static const struct drm_plane_funcs mdp5_plane_funcs = { .atomic_print_state = mdp5_plane_atomic_print_state, }; +static int mdp5_plane_prepare_fb (struct drm_plane *plane, +struct drm_plane_state *new_state) +{ +struct msm_drm_private *priv = plane->dev->dev_private; +struct msm_kms *kms = priv->kms; +bool needs_dirtyfb =to_mdp5_plane_state (new_state)->needs_dirtyfb; + +if (!new_state->fb) +return 0 ; + +drm_gem_plane_helper_prepare_fb (plane, new_state); + +return msm_framebuffer_prepare (new_state->fb, kms->aspace, needs_dirtyfb); +} +static void mdp5_plane_cleanup_fb (struct drm_plane *plane,struct drm_plane_state *old_state) {struct mdp5_kms *mdp5_kms =get_kms (plane);struct msm_kms *kms = &mdp5_kms->base.base;struct drm_framebuffer *fb = old_state->fb; +bool needed_dirtyfb =to_mdp5_plane_state (old_state)->needs_dirtyfb;if (!fb)return ;DBG ("%s: cleanup: FB[%u]" , plane->name, fb->base.id); -msm_framebuffer_cleanup (fb, kms->aspace); +msm_framebuffer_cleanup (fb, kms->aspace, needed_dirtyfb); } static int mdp5_plane_atomic_check_with_state(struct drm_crtc_state *crtc_state,
@@ -452,7 +469,7 @@ static void mdp5_plane_atomic_async_update(struct drm_plane *plane, }static const struct drm_plane_helper_funcs mdp5_plane_helper_funcs = { - .prepare_fb = msm_atomic_prepare_fb, + .prepare_fb = mdp5_plane_prepare_fb, .cleanup_fb = mdp5_plane_cleanup_fb, .atomic_check = mdp5_plane_atomic_check, .atomic_update = mdp5_plane_atomic_update,
drivers/gpu/drm/msm/msm_atomic.c +0 -15
@@ -5,7 +5,6 @@*/ #include <drm/drm_atomic_uapi.h> -#include <drm/drm_gem_atomic_helper.h> #include <drm/drm_vblank.h> #include "msm_atomic_trace.h"
@@ -13,20 +12,6 @@#include "msm_gem.h" #include "msm_kms.h" -int msm_atomic_prepare_fb (struct drm_plane *plane, -struct drm_plane_state *new_state) -{ -struct msm_drm_private *priv = plane->dev->dev_private; -struct msm_kms *kms = priv->kms; - -if (!new_state->fb) -return 0 ; - -drm_gem_plane_helper_prepare_fb (plane, new_state); - -return msm_framebuffer_prepare (new_state->fb, kms->aspace); -} -/* * Helpers to control vblanks while we flush.. basically just to ensure * that vblank accounting is switched on, so we get valid seqn/timestamp
drivers/gpu/drm/msm/msm_drv.h +2 -4
@@ -247,8 +247,6 @@ struct msm_format {struct msm_pending_timer ; -int msm_atomic_prepare_fb (struct drm_plane *plane, -struct drm_plane_state *new_state);int msm_atomic_init_pending_timer (struct msm_pending_timer *timer,struct msm_kms *kms,int crtc_idx);void msm_atomic_destroy_pending_timer (struct msm_pending_timer *timer);
@@ -308,9 +306,9 @@ int msm_gem_prime_pin(struct drm_gem_object *obj);void msm_gem_prime_unpin (struct drm_gem_object *obj);int msm_framebuffer_prepare (struct drm_framebuffer *fb, -struct msm_gem_address_space *aspace); +struct msm_gem_address_space *aspace,bool needs_dirtyfb);void msm_framebuffer_cleanup (struct drm_framebuffer *fb, -struct msm_gem_address_space *aspace); +struct msm_gem_address_space *aspace,bool needed_dirtyfb);uint32_t msm_framebuffer_iova (struct drm_framebuffer *fb,struct msm_gem_address_space *aspace,int plane);struct drm_gem_object *msm_framebuffer_bo (struct drm_framebuffer *fb,int plane);
drivers/gpu/drm/msm/msm_fb.c +34 -7
77 lines not on this page · raw message
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 325/779 drm/msm/dpu: Fix for non-visible planes
In reply to Greg Kroah-HartmanFrom: Rob Clark <[email protected]>
[ Upstream commit cb77085b1f0a86ef9dfba86b5f3ed6c3340c2ea3 ]
Fixes kms_cursor_crc --run-subtest cursor-offscreen.. when the cursor moves offscreen the plane becomes non-visible, so we need to skip over it in crtc atomic test and mixer setup.
Patchwork: https://patchwork.freedesktop.org/patch/492819/
--- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +6 -0
@@ -230,6 +230,9 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,if (!state)continue ; +if (!state->visible) +continue ; + pstate =to_dpu_plane_state (state); fb = state->fb;
@@ -976,6 +979,9 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,if (cnt >=DPU_STAGE_MAX *4 )continue ; +if (!pstate->visible) +continue ; + pstates[cnt].dpu_pstate = dpu_pstate; pstates[cnt].drm_pstate = pstate; pstates[cnt].stage = pstate->normalized_zpos;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 326/779 mt76: mt76x02u: fix possible memory leak in __mt76x02u_mcu_send_msg
In reply to Greg Kroah-HartmanFrom: Lorenzo Bianconi <[email protected]>
[ Upstream commit cffd93411575afd987788e2ec3cb8eaff70f0215 ]
Free the skb if mt76u_bulk_msg fails in __mt76x02u_mcu_send_msg routine.
--- drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c +1 -1
@@ -108,7 +108,7 @@ __mt76x02u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, ret =mt76u_bulk_msg (dev, skb->data, skb->len,NULL ,500 ,MT_EP_OUT_INBAND_CMD );if (ret) -return ret; + goto out;if (wait_resp) ret =mt76x02u_mcu_wait_resp (dev, seq);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 327/779 mt76: mt7615: do not update pm stats in case of error
In reply to Greg Kroah-HartmanFrom: Lorenzo Bianconi <[email protected]>
[ Upstream commit 79717c4eeeae9dec894794fbe8af72f08f03ebdd ]
Do not update pm stats if mt7615_mcu_fw_pmctrl returns an error.
--- drivers/net/wireless/mediatek/mt76/mt7615/mcu.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +5 -4
@@ -385,10 +385,11 @@ static int mt7615_mcu_fw_pmctrl(struct mt7615_dev *dev) }mt7622_trigger_hif_int (dev, false); - - pm->stats.last_doze_event = jiffies; - pm->stats.awake_time += pm->stats.last_doze_event - - pm->stats.last_wake_event; +if (!err) { + pm->stats.last_doze_event = jiffies; + pm->stats.awake_time += pm->stats.last_doze_event - + pm->stats.last_wake_event; + } out:mutex_unlock (&pm->mutex);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 328/779 ieee80211: add EHT 1K aggregation definitions
In reply to Greg Kroah-HartmanFrom: Mordechay Goodstein <[email protected]>
[ Upstream commit 2a2c86f15e17c5013b9897b67d895e64a25ae3cb ]
We add the fields for parsing extended ADDBA request/respond, and new max 1K aggregation for limit ADDBA request/respond.
Adjust drivers to use the proper macro, IEEE80211_MAX_AMPDU_BUF -> IEEE80211_MAX_AMPDU_BUF_HE.
--- drivers/net/wireless/ath/ath11k/mac.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 4 ++-- drivers/net/wireless/mediatek/mt76/mt7915/init.c | 4 ++-- include/linux/ieee80211.h | 6 +++++- net/mac80211/agg-rx.c | 2 +- 5 files changed, 11 insertions(+), 7 deletions(-)
drivers/net/wireless/ath/ath11k/mac.c +1 -1
@@ -6566,7 +6566,7 @@ static int __ath11k_mac_register(struct ath11k *ar) ar->hw->queues =ATH11K_HW_MAX_QUEUES ; ar->hw->wiphy->tx_queue_len =ATH11K_QUEUE_LEN ; ar->hw->offchannel_tx_hw_queue =ATH11K_HW_MAX_QUEUES -1 ; - ar->hw->max_rx_aggregation_subframes =IEEE80211_MAX_AMPDU_BUF ; + ar->hw->max_rx_aggregation_subframes =IEEE80211_MAX_AMPDU_BUF_HE ; ar->hw->vif_data_size =sizeof (struct ath11k_vif ); ar->hw->sta_data_size =sizeof (struct ath11k_sta );
drivers/net/wireless/intel/iwlwifi/mvm/ops.c +2 -2
@@ -761,12 +761,12 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,if (!hw)return NULL ; - hw->max_rx_aggregation_subframes =IEEE80211_MAX_AMPDU_BUF ; + hw->max_rx_aggregation_subframes =IEEE80211_MAX_AMPDU_BUF_HE ;if (cfg->max_tx_agg_size) hw->max_tx_aggregation_subframes = cfg->max_tx_agg_size;else - hw->max_tx_aggregation_subframes =IEEE80211_MAX_AMPDU_BUF ; + hw->max_tx_aggregation_subframes =IEEE80211_MAX_AMPDU_BUF_HE ; op_mode = hw->priv;
drivers/net/wireless/mediatek/mt76/mt7915/init.c +2 -2
@@ -217,8 +217,8 @@ mt7915_init_wiphy(struct ieee80211_hw *hw)struct wiphy *wiphy = hw->wiphy; hw->queues =4 ; - hw->max_rx_aggregation_subframes =IEEE80211_MAX_AMPDU_BUF ; - hw->max_tx_aggregation_subframes =IEEE80211_MAX_AMPDU_BUF ; + hw->max_rx_aggregation_subframes =IEEE80211_MAX_AMPDU_BUF_HE ; + hw->max_tx_aggregation_subframes =IEEE80211_MAX_AMPDU_BUF_HE ; hw->netdev_features =NETIF_F_RXCSUM ; hw->radiotap_timestamp.units_pos =
include/linux/ieee80211.h +5 -1
@@ -1023,6 +1023,8 @@ struct ieee80211_tpc_report_ie {#define IEEE80211_ADDBA_EXT_FRAG_LEVEL_MASK GENMASK(2, 1)#define IEEE80211_ADDBA_EXT_FRAG_LEVEL_SHIFT 1#define IEEE80211_ADDBA_EXT_NO_FRAG BIT(0) +#define IEEE80211_ADDBA_EXT_BUF_SIZE_MASK GENMASK(7, 5) +#define IEEE80211_ADDBA_EXT_BUF_SIZE_SHIFT 10struct ieee80211_addba_ext_ie {u8 data;
@@ -1697,10 +1699,12 @@ struct ieee80211_ht_operation {* A-MPDU buffer sizes * According to HT size varies from 8 to 64 frames * HE adds the ability to have up to 256 frames. +* EHT adds the ability to have up to 1K frames. */ #define IEEE80211_MIN_AMPDU_BUF 0x8#define IEEE80211_MAX_AMPDU_BUF_HT 0x40 -#define IEEE80211_MAX_AMPDU_BUF 0x100 +#define IEEE80211_MAX_AMPDU_BUF_HE 0x100 +#define IEEE80211_MAX_AMPDU_BUF_EHT 0x400/* Spatial Multiplexing Power Save Modes (for capability) */
net/mac80211/agg-rx.c +1 -1
@@ -310,7 +310,7 @@ void ___ieee80211_start_rx_ba_session(struct sta_info *sta, }if (sta->sta.he_cap.has_he) - max_buf_size =IEEE80211_MAX_AMPDU_BUF ; + max_buf_size =IEEE80211_MAX_AMPDU_BUF_HE ;else max_buf_size =IEEE80211_MAX_AMPDU_BUF_HT ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 329/779 mt76: mt7921: fix aggregation subframes setting to HE max
In reply to Greg Kroah-HartmanFrom: Deren Wu <[email protected]>
[ Upstream commit d5a50e6bd1972c481f82befa846dce0b9866f025 ]
mt7921/mt7922 support HE max aggregation subframes 256 for both tx/rx. Get better throughput then before.
--- drivers/net/wireless/mediatek/mt76/mt7921/init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7921/init.c +2 -2
@@ -49,8 +49,8 @@ mt7921_init_wiphy(struct ieee80211_hw *hw)struct wiphy *wiphy = hw->wiphy; hw->queues =4 ; - hw->max_rx_aggregation_subframes =64 ; - hw->max_tx_aggregation_subframes =128 ; + hw->max_rx_aggregation_subframes =IEEE80211_MAX_AMPDU_BUF_HE ; + hw->max_tx_aggregation_subframes =IEEE80211_MAX_AMPDU_BUF_HE ; hw->netdev_features =NETIF_F_RXCSUM ; hw->radiotap_timestamp.units_pos =
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 330/779 mt76: mt7921: enlarge maximum VHT MPDU length to 11454
In reply to Greg Kroah-HartmanFrom: Deren Wu <[email protected]>
[ Upstream commit 31f3248a75932b111bc90c66b1f6c7d89eedca8e ]
Enlarge maximum MPDU length to 11454 that both mt7921/mt7922 can support. After this fixing, we can get better performance.
--- drivers/net/wireless/mediatek/mt76/mt7921/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt7921/init.c +1 -1
@@ -219,7 +219,7 @@ int mt7921_register_device(struct mt7921_dev *dev)IEEE80211_HT_CAP_LDPC_CODING |IEEE80211_HT_CAP_MAX_AMSDU ; dev->mphy.sband_5g.sband.vht_cap.cap |= -IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 | +IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK |IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE | IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 331/779 mediatek: mt76: mac80211: Fix missing of_node_put() in mt76_led_init()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 0a14c1d0113f121151edf34333cdf212dd209190 ]
We should use of_node_put() for the reference 'np' returned by of_get_child_by_name() which will increase the refcount.
--- drivers/net/wireless/mediatek/mt76/mac80211.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/wireless/mediatek/mt76/mac80211.c +1 -0
@@ -123,6 +123,7 @@ static int mt76_led_init(struct mt76_dev *dev)if (!of_property_read_u32 (np,"led-sources" , &led_pin)) dev->led_pin = led_pin; dev->led_al =of_property_read_bool (np,"led-active-low" ); +of_node_put (np); }return led_classdev_register (dev->dev, &dev->led_cdev);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 332/779 mediatek: mt76: eeprom: fix missing of_node_put() in mt76_find_power_limits_node()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 3bd53ea02d77917c2314ec7be9e2d05be22f87d3 ]
We should use of_node_put() for the reference 'np' returned by of_get_child_by_name() which will increase the refcount.
--- drivers/net/wireless/mediatek/mt76/eeprom.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/eeprom.c +4 -1
@@ -146,10 +146,13 @@ mt76_find_power_limits_node(struct mt76_dev *dev) }if (mt76_string_prop_find (country, dev->alpha2) || -mt76_string_prop_find (regd, region_name)) +mt76_string_prop_find (regd, region_name)) { +of_node_put (np);return cur; + } } +of_node_put (np);return fallback; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 333/779 skmsg: Fix invalid last sg check in sk_msg_recvmsg()
In reply to Greg Kroah-HartmanFrom: Liu Jian <[email protected]>
[ Upstream commit 9974d37ea75f01b47d16072b5dad305bd8d23fcc ]
In sk_psock_skb_ingress_enqueue function, if the linear area + nr_frags + frag_list of the SKB has NR_MSG_FRAG_IDS blocks in total, skb_to_sgvec will return NR_MSG_FRAG_IDS, then msg->sg.end will be set to NR_MSG_FRAG_IDS, and in addition, (NR_MSG_FRAG_IDS - 1) is set to the last SG of msg. Recv the msg in sk_msg_recvmsg, when i is (NR_MSG_FRAG_IDS - 1), the sk_msg_iter_var_next(i) will change i to 0 (not NR_MSG_FRAG_IDS), the judgment condition "msg_rx->sg.start==msg_rx->sg.end" and
"i != msg_rx->sg.end" can not work.
As a result, the processed msg cannot be deleted from ingress_msg list. But the length of all the sge of the msg has changed to 0. Then the next recvmsg syscall will process the msg repeatedly, because the length of sge is 0, the -EFAULT error is always returned.
--- net/core/skmsg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/core/skmsg.c +2 -2
@@ -462,7 +462,7 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg,if (copied == len)break ; - }while (i != msg_rx->sg.end); + }while (!sg_is_last (sge));if (unlikely (peek)) { msg_rx =sk_psock_next_msg (psock, msg_rx);
@@ -472,7 +472,7 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg, } msg_rx->sg.start = i; -if (!sge->length && msg_rx->sg.start == msg_rx->sg.end) { +if (!sge->length &&sg_is_last (sge)) { msg_rx =sk_psock_dequeue_msg (psock);kfree_sk_msg (msg_rx); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 334/779 drm/exynos/exynos7_drm_decon: free resources when clk_set_parent() failed.
In reply to Greg Kroah-HartmanFrom: Jian Zhang <[email protected]>
[ Upstream commit 48b927770f8ad3f8cf4a024a552abf272af9f592 ]
In exynos7_decon_resume, When it fails, we must use clk_disable_unprepare() to free resource that have been used.
message")
--- drivers/gpu/drm/exynos/exynos7_drm_decon.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-)
drivers/gpu/drm/exynos/exynos7_drm_decon.c +13 -4
@@ -806,31 +806,40 @@ static int exynos7_decon_resume(struct device *dev)if (ret <0 ) {DRM_DEV_ERROR (dev,"Failed to prepare_enable the pclk [%d]\n" , ret); -return ret; + goto err_pclk_enable; } ret =clk_prepare_enable (ctx->aclk);if (ret <0 ) {DRM_DEV_ERROR (dev,"Failed to prepare_enable the aclk [%d]\n" , ret); -return ret; + goto err_aclk_enable; } ret =clk_prepare_enable (ctx->eclk);if (ret <0 ) {DRM_DEV_ERROR (dev,"Failed to prepare_enable the eclk [%d]\n" , ret); -return ret; + goto err_eclk_enable; } ret =clk_prepare_enable (ctx->vclk);if (ret <0 ) {DRM_DEV_ERROR (dev,"Failed to prepare_enable the vclk [%d]\n" , ret); -return ret; + goto err_vclk_enable; }return 0 ; + +err_vclk_enable: +clk_disable_unprepare (ctx->eclk); +err_eclk_enable: +clk_disable_unprepare (ctx->aclk); +err_aclk_enable: +clk_disable_unprepare (ctx->pclk); +err_pclk_enable: + return ret; }#endif
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 335/779 tcp: make retransmitted SKB fit into the send window
In reply to Greg Kroah-HartmanFrom: Yonglong Li <[email protected]>
[ Upstream commit 536a6c8e05f95e3d1118c40ae8b3022ee2d05d52 ]
current code of __tcp_retransmit_skb only check TCP_SKB_CB(skb)->seq in send window, and TCP_SKB_CB(skb)->seq_end maybe out of send window. If receiver has shrunk his window, and skb is out of new window, it should retransmit a smaller portion of the payload.
test packetdrill script:
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0 fcntl(3, F_GETFL) = 0x2 (flags O_RDWR)
+0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
+0 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress) +0 > S 0:0(0) win 65535 <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8>
+.05 < S. 0:0(0) ack 1 win 6000 <mss 1000,nop,nop,sackOK>
+0 > . 1:1(0) ack 1
+0 write(3, ..., 10000) = 10000
+0 > . 1:2001(2000) ack 1 win 65535
+0 > . 2001:4001(2000) ack 1 win 65535
+0 > . 4001:6001(2000) ack 1 win 65535
+.05 < . 1:1(0) ack 4001 win 1001
and tcpdump show:
192.168.226.67.55 > 192.0.2.1.8080: Flags [.], seq 1:2001, ack 1, win 65535, length 2000 192.168.226.67.55 > 192.0.2.1.8080: Flags [.], seq 2001:4001, ack 1, win 65535, length 2000 192.168.226.67.55 > 192.0.2.1.8080: Flags [P.], seq 4001:5001, ack 1, win 65535, length 1000 192.168.226.67.55 > 192.0.2.1.8080: Flags [.], seq 5001:6001, ack 1, win 65535, length 1000 192.0.2.1.8080 > 192.168.226.67.55: Flags [.], ack 4001, win 1001, length 0 192.168.226.67.55 > 192.0.2.1.8080: Flags [.], seq 5001:6001, ack 1, win 65535, length 1000 192.168.226.67.55 > 192.0.2.1.8080: Flags [P.], seq 4001:5001, ack 1, win 65535, length 1000
when cient retract window to 1001, send window is [4001,5002], but TLP send 5001-6001 packet which is out of send window.
--- net/ipv4/tcp_output.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-)
net/ipv4/tcp_output.c +16 -7
@@ -3145,7 +3145,7 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs)struct tcp_sock *tp =tcp_sk (sk);unsigned int cur_mss;int diff, len, err; - +int avail_wnd;/* Inconclusive MTU probe */ if (icsk->icsk_mtup.probe_size)
@@ -3167,17 +3167,25 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs)return -EHOSTUNREACH ;/* Routing failure or similar. */ cur_mss =tcp_current_mss (sk); + avail_wnd =tcp_wnd_end (tp) -TCP_SKB_CB (skb)->seq;/* If receiver has shrunk his window, and skb is out of * new window, do not retransmit it. The exception is the * case, when window is shrunk to zero. In this case -* our retransmit serves as a zero window probe. +* our retransmit of one segment serves as a zero window probe. */ -if (!before (TCP_SKB_CB (skb)->seq,tcp_wnd_end (tp)) && -TCP_SKB_CB (skb)->seq != tp->snd_una) -return -EAGAIN ; +if (avail_wnd <=0 ) { +if (TCP_SKB_CB (skb)->seq != tp->snd_una) +return -EAGAIN ; + avail_wnd = cur_mss; + } len = cur_mss * segs; +if (len > avail_wnd) { + len =rounddown (avail_wnd, cur_mss); +if (!len) + len = avail_wnd; + }if (skb->len > len) {if (tcp_fragment (sk,TCP_FRAG_IN_RTX_QUEUE , skb, len, cur_mss,GFP_ATOMIC ))
@@ -3191,8 +3199,9 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs) diff -=tcp_skb_pcount (skb);if (diff)tcp_adjust_pcount (sk, skb, diff); -if (skb->len < cur_mss) -tcp_retrans_try_collapse (sk, skb, cur_mss); + avail_wnd =min_t (int, avail_wnd, cur_mss); +if (skb->len < avail_wnd) +tcp_retrans_try_collapse (sk, skb, avail_wnd); }/* RFC3168, section 6.1.1.1. ECN fallback */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 336/779 libbpf: Fix the name of a reused map
In reply to Greg Kroah-HartmanFrom: Anquan Wu <[email protected]>
[ Upstream commit bf3f00378524adae16628cbadbd11ba7211863bb ]
BPF map name is limited to BPF_OBJ_NAME_LEN.
A map name is defined as being longer than BPF_OBJ_NAME_LEN, it will be truncated to BPF_OBJ_NAME_LEN when a userspace program calls libbpf to create the map. A pinned map also generates a path in the /sys. If the previous program wanted to reuse the map, it can not get bpf_map by name, because the name of the map is only partially the same as the name which get from pinned path.
The syscall information below show that map name "process_pinned_map" is truncated to "process_pinned_".
bpf(BPF_OBJ_GET, {pathname="/sys/fs/bpf/process_pinned_map",
bpf_fd=0, file_flags=0}, 144) = -1 ENOENT (No such file or directory)
bpf(BPF_MAP_CREATE, {map_type=BPF_MAP_TYPE_HASH, key_size=4,
value_size=4,max_entries=1024, map_flags=0, inner_map_fd=0,
map_name="process_pinned_",map_ifindex=0, btf_fd=3, btf_key_type_id=6,
btf_value_type_id=10,btf_vmlinux_value_type_id=0}, 72) = 4This patch check that if the name of pinned map are the same as the actual name for the first (BPF_OBJ_NAME_LEN - 1),
bpf map still uses the name which is included in bpf object.
--- tools/lib/bpf/libbpf.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
tools/lib/bpf/libbpf.c +7 -2
@@ -3942,7 +3942,7 @@ static int bpf_get_map_info_from_fdinfo(int fd, struct bpf_map_info *info)int bpf_map__reuse_fd (struct bpf_map *map,int fd) {struct bpf_map_info info = {}; -__u32 len =sizeof (info); +__u32 len =sizeof (info), name_len;int new_fd, err;char *new_name;
@@ -3952,7 +3952,12 @@ int bpf_map__reuse_fd(struct bpf_map *map, int fd)if (err)return libbpf_err (err); - new_name =strdup (info.name); + name_len =strlen (info.name); +if (name_len ==BPF_OBJ_NAME_LEN -1 &&strncmp (map->name, info.name, name_len) ==0 ) + new_name =strdup (map->name); +else + new_name =strdup (info.name); +if (!new_name)return libbpf_err (-errno);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 337/779 selftests: timers: valid-adjtimex: build fix for newer toolchains
In reply to Greg Kroah-HartmanFrom: Wolfram Sang <[email protected]>
[ Upstream commit 9a162977d20436be5678a8e21a8e58eb4616d86a ]
Toolchains with an include file 'sys/timex.h' based on 3.18 will have a 'clock_adjtime' definition added, so it can't be static in the code:
valid-adjtimex.c:43:12: error: static declaration of ‘clock_adjtime’ follows non-static declaration
--- tools/testing/selftests/timers/valid-adjtimex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/timers/valid-adjtimex.c +1 -1
@@ -40,7 +40,7 @@#define ADJ_SETOFFSET 0x0100#include <sys/syscall.h> -static int clock_adjtime (clockid_t id,struct timex *tx) +int clock_adjtime (clockid_t id,struct timex *tx) {return syscall (__NR_clock_adjtime, id, tx); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 338/779 selftests: timers: clocksource-switch: fix passing errors from child
In reply to Greg Kroah-HartmanFrom: Wolfram Sang <[email protected]>
[ Upstream commit 4d8f52ac5fa9eede7b7aa2f2d67c841d9eeb655f ]
The return value from system() is a waitpid-style integer. Do not return it directly because with the implicit masking in exit() it will always return 0. Access it with appropriate macros to really pass on errors.
--- tools/testing/selftests/timers/clocksource-switch.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
tools/testing/selftests/timers/clocksource-switch.c +3 -3
@@ -110,10 +110,10 @@ int run_tests(int secs)sprintf (buf,"./inconsistency-check -t %i" , secs); ret =system (buf); -if (ret) -return ret; +if (WIFEXITED (ret) &&WEXITSTATUS (ret)) +return WEXITSTATUS (ret); ret =system ("./nanosleep" ); -return ret; +return WIFEXITED (ret) ?WEXITSTATUS (ret) :0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 339/779 bpf: Fix subprog names in stack traces.
In reply to Greg Kroah-HartmanFrom: Alexei Starovoitov <[email protected]>
[ Upstream commit 9c7c48d6a1e2eb5192ad5294c1c4dbd42a88e88b ]
The commit 7337224fc150 ("bpf: Improve the info.func_info and info.func_info_rec_size behavior") accidently made bpf_prog_ksym_set_name() conservative for bpf subprograms.
Fixed it so instead of "bpf_prog_tag_F" the stack traces print "bpf_prog_tag_full_subprog_name".
--- kernel/bpf/verifier.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
kernel/bpf/verifier.c +1 -3
@@ -12445,6 +12445,7 @@ static int jit_subprogs(struct bpf_verifier_env *env)/* Below members will be freed only at prog->aux */ func[i]->aux->btf = prog->aux->btf; func[i]->aux->func_info = prog->aux->func_info; + func[i]->aux->func_info_cnt = prog->aux->func_info_cnt; func[i]->aux->poke_tab = prog->aux->poke_tab; func[i]->aux->size_poke_tab = prog->aux->size_poke_tab;
@@ -12457,9 +12458,6 @@ static int jit_subprogs(struct bpf_verifier_env *env) poke->aux = func[i]->aux; } -/* Use bpf_prog_F_tag to indicate functions in stack traces. -* Long term would need debug info to populate names -*/ func[i]->aux->name[0 ] ='F' ; func[i]->aux->stack_depth = env->subprog_info[i].stack_depth; func[i]->jit_requested =1 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 340/779 fs: check FMODE_LSEEK to control internal pipe splicing
In reply to Greg Kroah-HartmanFrom: Jason A. Donenfeld <[email protected]>
[ Upstream commit 97ef77c52b789ec1411d360ed99dca1efe4b2c81 ]
The original direct splicing mechanism from Jens required the input to be a regular file because it was avoiding the special socket case. It also recognized blkdevs as being close enough to a regular file. But it forgot about chardevs, which behave the same way and work fine here.
This is an okayish heuristic, but it doesn't totally work. For example, a few chardevs should be spliceable here. And a few regular files shouldn't. This patch fixes this by instead checking whether FMODE_LSEEK is set, which represents decently enough what we need rewinding for when splicing to internal pipes.
--- fs/splice.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
fs/splice.c +4 -6
@@ -814,17 +814,15 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, {struct pipe_inode_info *pipe;long ret, bytes; -umode_t i_mode;size_t len;int i, flags, more;/* -* We require the input being a regular file, as we don't want to -* randomly drop data for eg socket -> socket splicing. Use the -* piped splicing for that! +* We require the input to be seekable, as we don't want to randomly +* drop data for eg socket -> socket splicing. Use the piped splicing +* for that! */ - i_mode =file_inode (in)->i_mode; -if (unlikely (!S_ISREG (i_mode) && !S_ISBLK (i_mode))) +if (unlikely (!(in->f_mode &FMODE_LSEEK )))return -EINVAL ;/*
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 341/779 media: cedrus: h265: Fix flag name
In reply to Greg Kroah-HartmanFrom: Jernej Skrabec <[email protected]>
[ Upstream commit 104a70e1d0bcef28db13c4192b8729086089651c ]
Bit 21 in register 0x24 (slice header info 1) actually represents negated version of low delay flag. This can be seen in vendor Cedar library source code. While this flag is not part of the standard, it can be found in reference HEVC implementation.
Fix macro name and change it to flag.
--- drivers/staging/media/sunxi/cedrus/cedrus_h265.c | 4 +++- drivers/staging/media/sunxi/cedrus/cedrus_regs.h | 3 +-- 2 files changed, 4 insertions(+), 3 deletions(-)
drivers/staging/media/sunxi/cedrus/cedrus_h265.c +3 -1
@@ -495,7 +495,6 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx, reg =VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_TC_OFFSET_DIV2 (slice_params->slice_tc_offset_div2) |VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_BETA_OFFSET_DIV2 (slice_params->slice_beta_offset_div2) | -VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_POC_BIGEST_IN_RPS_ST (decode_params->num_poc_st_curr_after ==0 ) |VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CR_QP_OFFSET (slice_params->slice_cr_qp_offset) |VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CB_QP_OFFSET (slice_params->slice_cb_qp_offset) |VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_QP_DELTA (slice_params->slice_qp_delta);
@@ -508,6 +507,9 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED , slice_params->flags); +if (decode_params->num_poc_st_curr_after ==0 ) + reg |=VE_DEC_H265_DEC_SLICE_HDR_INFO1_FLAG_SLICE_NOT_LOW_DELAY ; +cedrus_write (dev,VE_DEC_H265_DEC_SLICE_HDR_INFO1 , reg); chroma_log2_weight_denom = pred_weight_table->luma_log2_weight_denom +
drivers/staging/media/sunxi/cedrus/cedrus_regs.h +1 -2
@@ -377,13 +377,12 @@#define VE_DEC_H265_DEC_SLICE_HDR_INFO1_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED BIT(23)#define VE_DEC_H265_DEC_SLICE_HDR_INFO1_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED BIT(22) +#define VE_DEC_H265_DEC_SLICE_HDR_INFO1_FLAG_SLICE_NOT_LOW_DELAY BIT(21)#define VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_TC_OFFSET_DIV2 (v) \ SHIFT_AND_MASK_BITS(v, 31, 28)#define VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_BETA_OFFSET_DIV2 (v) \ SHIFT_AND_MASK_BITS(v, 27, 24) -#define VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_POC_BIGEST_IN_RPS_ST (v) \ - ((v) ? BIT(21) : 0)#define VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CR_QP_OFFSET (v) \ SHIFT_AND_MASK_BITS(v, 20, 16)#define VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CB_QP_OFFSET (v) \
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 342/779 media: hantro: postproc: Fix motion vector space size
In reply to Greg Kroah-HartmanFrom: Ezequiel Garcia <[email protected]>
[ Upstream commit 9393761aec4c56b7f2f19d21f806d316731401c1 ]
When the post-processor hardware block is enabled, the driver allocates an internal queue of buffers for the decoder enginer, and uses the vb2 queue for the post-processor engine.
For instance, on a G1 core, the decoder engine produces NV12 buffers and the post-processor engine can produce YUY2 buffers. The decoder engine expects motion vectors to be appended to the NV12 buffers, but this is only required for CODECs that need motion vectors, such as H.264.
Fix the post-processor logic accordingly.
--- drivers/staging/media/hantro/hantro_postproc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/staging/media/hantro/hantro_postproc.c +4 -3
@@ -132,9 +132,10 @@ int hantro_postproc_alloc(struct hantro_ctx *ctx)unsigned int num_buffers = cap_queue->num_buffers;unsigned int i, buf_size; - buf_size = ctx->dst_fmt.plane_fmt[0 ].sizeimage + -hantro_h264_mv_size (ctx->dst_fmt.width, - ctx->dst_fmt.height); + buf_size = ctx->dst_fmt.plane_fmt[0 ].sizeimage; +if (ctx->vpu_src_fmt->fourcc ==V4L2_PIX_FMT_H264_SLICE ) + buf_size +=hantro_h264_mv_size (ctx->dst_fmt.width, + ctx->dst_fmt.height);for (i =0 ; i < num_buffers; ++i) {struct hantro_aux_buf *priv = &ctx->postproc.dec_q[i];
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 343/779 media: hantro: Simplify postprocessor
In reply to Greg Kroah-HartmanFrom: Ezequiel Garcia <[email protected]>
[ Upstream commit 53a3e71095c572333ceea30762565dbedec951ca ]
Add a 'postprocessed' boolean property to struct hantro_fmt to signal that a format is produced by the post-processor. This will allow to introduce the G2 post-processor in a simple way.
--- drivers/staging/media/hantro/hantro.h | 2 ++ drivers/staging/media/hantro/hantro_postproc.c | 8 +------- drivers/staging/media/hantro/imx8m_vpu_hw.c | 1 + drivers/staging/media/hantro/rockchip_vpu_hw.c | 1 + drivers/staging/media/hantro/sama5d4_vdec_hw.c | 1 + 5 files changed, 6 insertions(+), 7 deletions(-)
drivers/staging/media/hantro/hantro.h +2 -0
@@ -262,6 +262,7 @@ struct hantro_ctx {* @max_depth: Maximum depth, for bitstream formats * @enc_fmt: Format identifier for encoder registers. * @frmsize: Supported range of frame sizes (only for bitstream formats). +* @postprocessed: Indicates if this format needs the post-processor. */ struct hantro_fmt {char *name;
@@ -271,6 +272,7 @@ struct hantro_fmt {int max_depth;enum hantro_enc_fmt enc_fmt;struct v4l2_frmsize_stepwise frmsize; +bool postprocessed; };struct hantro_reg {
drivers/staging/media/hantro/hantro_postproc.c +1 -7
@@ -53,15 +53,9 @@ const struct hantro_postproc_regs hantro_g1_postproc_regs = {bool hantro_needs_postproc (const struct hantro_ctx *ctx,const struct hantro_fmt *fmt) { -struct hantro_dev *vpu = ctx->dev; -if (ctx->is_encoder)return false; - -if (!vpu->variant->postproc_fmts) -return false; - -return fmt->fourcc !=V4L2_PIX_FMT_NV12 ; +return fmt->postprocessed; }void hantro_postproc_enable (struct hantro_ctx *ctx)
drivers/staging/media/hantro/imx8m_vpu_hw.c +1 -0
@@ -82,6 +82,7 @@ static const struct hantro_fmt imx8m_vpu_postproc_fmts[] = { { .fourcc = V4L2_PIX_FMT_YUYV, .codec_mode = HANTRO_MODE_NONE, + .postprocessed = true, }, };
drivers/staging/media/hantro/rockchip_vpu_hw.c +1 -0
@@ -62,6 +62,7 @@ static const struct hantro_fmt rockchip_vpu1_postproc_fmts[] = { { .fourcc = V4L2_PIX_FMT_YUYV, .codec_mode = HANTRO_MODE_NONE, + .postprocessed = true, }, };
drivers/staging/media/hantro/sama5d4_vdec_hw.c +1 -0
@@ -15,6 +15,7 @@ static const struct hantro_fmt sama5d4_vdec_postproc_fmts[] = { { .fourcc = V4L2_PIX_FMT_YUYV, .codec_mode = HANTRO_MODE_NONE, + .postprocessed = true, }, };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 344/779 media: hevc: Embedded indexes in RPS
In reply to Greg Kroah-HartmanFrom: Benjamin Gaignard <[email protected]>
[ Upstream commit d95a63daca85f4bca3b70e622c75586b5bf0ea5c ]
Reference Picture Set lists provide indices of short and long term reference in DBP array.
Fix Hantro to not do a look up in DBP entries.
Make documentation more clear about it.
[hverkuil: fix typo in commit log]
--- .../media/v4l/ext-ctrls-codec.rst | 6 ++--- .../staging/media/hantro/hantro_g2_hevc_dec.c | 25 +++++-------------- 2 files changed, 9 insertions(+), 22 deletions(-)
Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +3 -3
@@ -3326,15 +3326,15 @@ enum v4l2_mpeg_video_hevc_size_of_length_field - * - __u8 - ``poc_st_curr_before[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]`` - PocStCurrBefore as described in section 8.3.2 "Decoding process for reference - picture set. + picture set": provides the index of the short term before references in DPB array. * - __u8 - ``poc_st_curr_after[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]`` - PocStCurrAfter as described in section 8.3.2 "Decoding process for reference - picture set. + picture set": provides the index of the short term after references in DPB array. * - __u8 - ``poc_lt_curr[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]`` - PocLtCurr as described in section 8.3.2 "Decoding process for reference - picture set. + picture set": provides the index of the long term references in DPB array. * - __u64 - ``flags`` - See :ref:`Decode Parameters Flags <hevc_decode_params_flags>`
drivers/staging/media/hantro/hantro_g2_hevc_dec.c +6 -19
@@ -264,24 +264,11 @@ static void set_params(struct hantro_ctx *ctx)hantro_reg_write (vpu, &g2_apf_threshold,8 ); } -static int find_ref_pic_index (const struct v4l2_hevc_dpb_entry *dpb,int pic_order_cnt) -{ -int i; - -for (i =0 ; i <V4L2_HEVC_DPB_ENTRIES_NUM_MAX ; i++) { -if (dpb[i].pic_order_cnt[0 ] == pic_order_cnt) -return i; - } - -return 0x0 ; -} -static void set_ref_pic_list (struct hantro_ctx *ctx) {const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls;struct hantro_dev *vpu = ctx->dev;const struct v4l2_ctrl_hevc_decode_params *decode_params = ctrls->decode_params; -const struct v4l2_hevc_dpb_entry *dpb = decode_params->dpb;u32 list0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX ] = {};u32 list1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX ] = {};static const struct hantro_reg ref_pic_regs0[] = {
@@ -325,11 +312,11 @@ static void set_ref_pic_list(struct hantro_ctx *ctx)/* List 0 contains: short term before, short term after and long term */ j =0 ;for (i =0 ; i < decode_params->num_poc_st_curr_before && j <ARRAY_SIZE (list0); i++) - list0[j++] =find_ref_pic_index (dpb, decode_params->poc_st_curr_before[i]); + list0[j++] = decode_params->poc_st_curr_before[i];for (i =0 ; i < decode_params->num_poc_st_curr_after && j <ARRAY_SIZE (list0); i++) - list0[j++] =find_ref_pic_index (dpb, decode_params->poc_st_curr_after[i]); + list0[j++] = decode_params->poc_st_curr_after[i];for (i =0 ; i < decode_params->num_poc_lt_curr && j <ARRAY_SIZE (list0); i++) - list0[j++] =find_ref_pic_index (dpb, decode_params->poc_lt_curr[i]); + list0[j++] = decode_params->poc_lt_curr[i];/* Fill the list, copying over and over */ i =0 ;
@@ -338,11 +325,11 @@ static void set_ref_pic_list(struct hantro_ctx *ctx) j =0 ;for (i =0 ; i < decode_params->num_poc_st_curr_after && j <ARRAY_SIZE (list1); i++) - list1[j++] =find_ref_pic_index (dpb, decode_params->poc_st_curr_after[i]); + list1[j++] = decode_params->poc_st_curr_after[i];for (i =0 ; i < decode_params->num_poc_st_curr_before && j <ARRAY_SIZE (list1); i++) - list1[j++] =find_ref_pic_index (dpb, decode_params->poc_st_curr_before[i]); + list1[j++] = decode_params->poc_st_curr_before[i];for (i =0 ; i < decode_params->num_poc_lt_curr && j <ARRAY_SIZE (list1); i++) - list1[j++] =find_ref_pic_index (dpb, decode_params->poc_lt_curr[i]); + list1[j++] = decode_params->poc_lt_curr[i]; i =0 ;while (j <ARRAY_SIZE (list1))
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 345/779 media: staging: media: hantro: Fix typos
In reply to Greg Kroah-HartmanFrom: Sebastian Fricke <[email protected]>
[ Upstream commit d8f6f1c56d5469e22eeb7cc1f3580b29e2f0fef5 ]
Fix typos in comments within the Hantro driver.
--- drivers/staging/media/hantro/hantro_g2_hevc_dec.c | 2 +- drivers/staging/media/hantro/hantro_hevc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/staging/media/hantro/hantro_g2_hevc_dec.c +1 -1
@@ -413,7 +413,7 @@ static int set_ref(struct hantro_ctx *ctx)set_ref_pic_list (ctx); -/* We will only keep the references picture that are still used */ +/* We will only keep the reference pictures that are still used */ ctx->hevc_dec.ref_bufs_used =0 ;/* Set up addresses of DPB buffers */
drivers/staging/media/hantro/hantro_hevc.c +1 -1
@@ -98,7 +98,7 @@ dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx,struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec;int i; -/* Find the reference buffer in already know ones */ +/* Find the reference buffer in already known ones */ for (i =0 ; i <NUM_REF_PICTURES ; i++) {if (hevc_dec->ref_bufs_poc[i] == poc) { hevc_dec->ref_bufs_used |=1 << i;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 346/779 wifi: wil6210: debugfs: fix info leak in wil_write_file_wmi()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 7a4836560a6198d245d5732e26f94898b12eb760 ]
The simple_write_to_buffer() function will succeed if even a single byte is initialized. However, we need to initialize the whole buffer to prevent information leaks. Just use memdup_user().
--- drivers/net/wireless/ath/wil6210/debugfs.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-)
drivers/net/wireless/ath/wil6210/debugfs.c +4 -10
@@ -1012,18 +1012,12 @@ static ssize_t wil_write_file_wmi(struct file *file, const char __user *buf,u16 cmdid;int rc, rc1; -if (cmdlen <0 ) +if (cmdlen <0 || *ppos !=0 )return -EINVAL ; - wmi =kmalloc (len,GFP_KERNEL ); -if (!wmi) -return -ENOMEM ; - - rc =simple_write_to_buffer (wmi, len, ppos, buf, len); -if (rc <0 ) { -kfree (wmi); -return rc; - } + wmi =memdup_user (buf, len); +if (IS_ERR (wmi)) +return PTR_ERR (wmi); cmd = (cmdlen >0 ) ? &wmi[1 ] :NULL ; cmdid =le16_to_cpu (wmi->command_id);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 347/779 wifi: p54: Fix an error handling path in p54spi_probe()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 83781f0162d080fec7dcb911afd1bc2f5ad04471 ]
If an error occurs after a successful call to p54spi_request_firmware(), it must be undone by a corresponding release_firmware() as already done in the error handling path of p54spi_request_firmware() and in the .remove() function.
Add the missing call in the error handling path and remove it from p54spi_request_firmware() now that it is the responsibility of the caller to release the firmware
--- drivers/net/wireless/intersil/p54/p54spi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/wireless/intersil/p54/p54spi.c +2 -1
@@ -164,7 +164,7 @@ static int p54spi_request_firmware(struct ieee80211_hw *dev) ret =p54_parse_firmware (dev, priv->firmware);if (ret) { -release_firmware (priv->firmware); +/* the firmware is released by the caller */ return ret; }
@@ -659,6 +659,7 @@ static int p54spi_probe(struct spi_device *spi)return 0 ; err_free_common: +release_firmware (priv->firmware);free_irq (gpio_to_irq (p54spi_gpio_irq), spi); err_free_gpio_irq:gpio_free (p54spi_gpio_irq);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 348/779 wifi: p54: add missing parentheses in p54_flush()
In reply to Greg Kroah-HartmanFrom: Rustam Subkhankulov <[email protected]>
[ Upstream commit bcfd9d7f6840b06d5988c7141127795cf405805e ]
The assignment of the value to the variable total in the loop condition must be enclosed in additional parentheses, since otherwise, in accordance with the precedence of the operators, the conjunction will be performed first, and only then the assignment.
Due to this error, a warning later in the function after the loop may not occur in the situation when it should.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/net/wireless/intersil/p54/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/intersil/p54/main.c +1 -1
@@ -682,7 +682,7 @@ static void p54_flush(struct ieee80211_hw *dev, struct ieee80211_vif *vif,* queues have already been stopped and no new frames can sneak * up from behind. */ -while ((total =p54_flush_count (priv) && i--)) { +while ((total =p54_flush_count (priv)) && i--) {/* waste time */ msleep (20 ); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 349/779 selftests/bpf: fix a test for snprintf() overflow
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit c5d22f4cfe8dfb93f1db0a1e7e2e7ebc41395d98 ]
The snprintf() function returns the number of bytes which *would* have been copied if there were space. In other words, it can be
Quoted 1 line
sizeof(pin_path).
--- tools/testing/selftests/bpf/prog_tests/btf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/bpf/prog_tests/btf.c +1 -1
@@ -4913,7 +4913,7 @@ static void do_test_pprint(int test_num) ret =snprintf (pin_path,sizeof (pin_path),"%s/%s" ,"/sys/fs/bpf" , test->map_name); -if (CHECK (ret ==sizeof (pin_path),"pin_path %s/%s is too long" , +if (CHECK (ret >=sizeof (pin_path),"pin_path %s/%s is too long" ,"/sys/fs/bpf" , test->map_name)) { err =-1 ; goto done;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 350/779 libbpf: fix an snprintf() overflow check
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit b77ffb30cfc5f58e957571d8541c6a7e3da19221 ]
The snprintf() function returns the number of bytes it *would* have copied if there were enough space. So it can return > the sizeof(gen->attach_target).
--- tools/lib/bpf/gen_loader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/lib/bpf/gen_loader.c +1 -1
@@ -480,7 +480,7 @@ void bpf_gen__record_attach_target(struct bpf_gen *gen, const char *attach_name, gen->attach_kind = kind; ret =snprintf (gen->attach_target,sizeof (gen->attach_target),"%s%s" , prefix, attach_name); -if (ret ==sizeof (gen->attach_target)) +if (ret >=sizeof (gen->attach_target)) gen->error = -ENOSPC ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 351/779 can: pch_can: do not report txerr and rxerr during bus-off
In reply to Greg Kroah-HartmanFrom: Vincent Mailhol <[email protected]>
[ Upstream commit 3a5c7e4611ddcf0ef37a3a17296b964d986161a6 ]
During bus off, the error count is greater than 255 and can not fit in a u8.
--- drivers/net/can/pch_can.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/can/pch_can.c +3 -3
@@ -496,6 +496,9 @@ static void pch_can_error(struct net_device *ndev, u32 status) cf->can_id |=CAN_ERR_BUSOFF ; priv->can.can_stats.bus_off++;can_bus_off (ndev); + }else { + cf->data[6 ] = errc &PCH_TEC ; + cf->data[7 ] = (errc &PCH_REC ) >>8 ; } errc =ioread32 (&priv->regs->errc);
@@ -556,9 +559,6 @@ static void pch_can_error(struct net_device *ndev, u32 status)break ; } - cf->data[6 ] = errc &PCH_TEC ; - cf->data[7 ] = (errc &PCH_REC ) >>8 ; - priv->can.state = state;netif_receive_skb (skb);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 352/779 can: rcar_can: do not report txerr and rxerr during bus-off
In reply to Greg Kroah-HartmanFrom: Vincent Mailhol <[email protected]>
[ Upstream commit a37b7245e831a641df360ca41db6a71c023d3746 ]
During bus off, the error count is greater than 255 and can not fit in a u8.
--- drivers/net/can/rcar/rcar_can.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/can/rcar/rcar_can.c +4 -4
@@ -235,11 +235,8 @@ static void rcar_can_error(struct net_device *ndev)if (eifr & (RCAR_CAN_EIFR_EWIF |RCAR_CAN_EIFR_EPIF )) { txerr =readb (&priv->regs->tecr); rxerr =readb (&priv->regs->recr); -if (skb) { +if (skb) cf->can_id |=CAN_ERR_CRTL ; - cf->data[6 ] = txerr; - cf->data[7 ] = rxerr; - } }if (eifr &RCAR_CAN_EIFR_BEIF ) {int rx_errors =0 , tx_errors =0 ;
@@ -339,6 +336,9 @@ static void rcar_can_error(struct net_device *ndev)can_bus_off (ndev);if (skb) cf->can_id |=CAN_ERR_BUSOFF ; + }else if (skb) { + cf->data[6 ] = txerr; + cf->data[7 ] = rxerr; }if (eifr &RCAR_CAN_EIFR_ORIF ) {netdev_dbg (priv->ndev,"Receive overrun error interrupt\n" );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 353/779 can: sja1000: do not report txerr and rxerr during bus-off
In reply to Greg Kroah-HartmanFrom: Vincent Mailhol <[email protected]>
[ Upstream commit 164d7cb2d5a30f1b3a5ab4fab1a27731fb1494a8 ]
During bus off, the error count is greater than 255 and can not fit in a u8.
--- drivers/net/can/sja1000/sja1000.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/net/can/sja1000/sja1000.c +4 -3
@@ -404,9 +404,6 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) txerr = priv->read_reg (priv,SJA1000_TXERR ); rxerr = priv->read_reg (priv,SJA1000_RXERR ); - cf->data[6 ] = txerr; - cf->data[7 ] = rxerr; -if (isrc &IRQ_DOI ) {/* data overrun interrupt */ netdev_dbg (dev,"data overrun interrupt\n" );
@@ -428,6 +425,10 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)else state =CAN_STATE_ERROR_ACTIVE ; } +if (state !=CAN_STATE_BUS_OFF ) { + cf->data[6 ] = txerr; + cf->data[7 ] = rxerr; + }if (isrc &IRQ_BEI ) {/* bus error interrupt */ priv->can.can_stats.bus_error++;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 354/779 can: hi311x: do not report txerr and rxerr during bus-off
In reply to Greg Kroah-HartmanFrom: Vincent Mailhol <[email protected]>
[ Upstream commit a22bd630cfff496b270211745536e50e98eb3a45 ]
During bus off, the error count is greater than 255 and can not fit in a u8.
--- drivers/net/can/spi/hi311x.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/net/can/spi/hi311x.c +3 -2
@@ -670,8 +670,6 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id) txerr =hi3110_read (spi,HI3110_READ_TEC ); rxerr =hi3110_read (spi,HI3110_READ_REC ); - cf->data[6 ] = txerr; - cf->data[7 ] = rxerr; tx_state = txerr >= rxerr ? new_state :0 ; rx_state = txerr <= rxerr ? new_state :0 ;can_change_state (net, cf, tx_state, rx_state);
@@ -684,6 +682,9 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id)hi3110_hw_sleep (spi);break ; } + }else { + cf->data[6 ] = txerr; + cf->data[7 ] = rxerr; } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 355/779 can: sun4i_can: do not report txerr and rxerr during bus-off
In reply to Greg Kroah-HartmanFrom: Vincent Mailhol <[email protected]>
[ Upstream commit 0ac15a8f661b941519379831d09bfb12271b23ee ]
During bus off, the error count is greater than 255 and can not fit in a u8.
--- drivers/net/can/sun4i_can.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
drivers/net/can/sun4i_can.c +4 -5
@@ -525,11 +525,6 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status) rxerr = (errc >>16 ) &0xFF ; txerr = errc &0xFF ; -if (skb) { - cf->data[6 ] = txerr; - cf->data[7 ] = rxerr; - } -if (isrc &SUN4I_INT_DATA_OR ) {/* data overrun interrupt */ netdev_dbg (dev,"data overrun interrupt\n" );
@@ -560,6 +555,10 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)else state =CAN_STATE_ERROR_ACTIVE ; } +if (skb && state !=CAN_STATE_BUS_OFF ) { + cf->data[6 ] = txerr; + cf->data[7 ] = rxerr; + }if (isrc &SUN4I_INT_BUS_ERR ) {/* bus error interrupt */ netdev_dbg (dev,"bus error interrupt\n" );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 356/779 can: kvaser_usb_hydra: do not report txerr and rxerr during bus-off
In reply to Greg Kroah-HartmanFrom: Vincent Mailhol <[email protected]>
[ Upstream commit 936e90595376e64b6247c72d3ea8b8b164b7ac96 ]
During bus off, the error count is greater than 255 and can not fit in a u8.
--- drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c +8 -4
@@ -916,8 +916,10 @@ static void kvaser_usb_hydra_update_state(struct kvaser_usb_net_priv *priv, new_state < CAN_STATE_BUS_OFF) priv->can.can_stats.restarts++; - cf->data[6 ] = bec->txerr; - cf->data[7 ] = bec->rxerr; +if (new_state !=CAN_STATE_BUS_OFF ) { + cf->data[6 ] = bec->txerr; + cf->data[7 ] = bec->rxerr; + } stats = &netdev->stats; stats->rx_packets++;
@@ -1071,8 +1073,10 @@ kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv, shhwtstamps->hwtstamp = hwtstamp; cf->can_id |=CAN_ERR_BUSERROR ; - cf->data[6 ] = bec.txerr; - cf->data[7 ] = bec.rxerr; +if (new_state !=CAN_STATE_BUS_OFF ) { + cf->data[6 ] = bec.txerr; + cf->data[7 ] = bec.rxerr; + } stats->rx_packets++; stats->rx_bytes += cf->len;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 357/779 can: kvaser_usb_leaf: do not report txerr and rxerr during bus-off
In reply to Greg Kroah-HartmanFrom: Vincent Mailhol <[email protected]>
[ Upstream commit a57732084e06791d37ea1ea447cca46220737abd ]
During bus off, the error count is greater than 255 and can not fit in a u8.
--- drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +4 -2
@@ -857,8 +857,10 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,break ; } - cf->data[6 ] = es->txerr; - cf->data[7 ] = es->rxerr; +if (new_state !=CAN_STATE_BUS_OFF ) { + cf->data[6 ] = es->txerr; + cf->data[7 ] = es->rxerr; + } stats->rx_packets++; stats->rx_bytes += cf->len;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 358/779 can: usb_8dev: do not report txerr and rxerr during bus-off
In reply to Greg Kroah-HartmanFrom: Vincent Mailhol <[email protected]>
[ Upstream commit aebe8a2433cd090ccdc222861f44bddb75eb01de ]
During bus off, the error count is greater than 255 and can not fit in a u8.
--- drivers/net/can/usb/usb_8dev.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/net/can/usb/usb_8dev.c +4 -3
@@ -442,9 +442,10 @@ static void usb_8dev_rx_err_msg(struct usb_8dev_priv *priv,if (rx_errors) stats->rx_errors++; - - cf->data[6 ] = txerr; - cf->data[7 ] = rxerr; +if (priv->can.state !=CAN_STATE_BUS_OFF ) { + cf->data[6 ] = txerr; + cf->data[7 ] = rxerr; + } priv->bec.txerr = txerr; priv->bec.rxerr = rxerr;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 359/779 can: error: specify the values of data[5..7] of CAN error frames
In reply to Greg Kroah-HartmanFrom: Vincent Mailhol <[email protected]>
[ Upstream commit e70a3263a7eed768d5f947b8f2aff8d2a79c9d97 ]
Currently, data[5..7] of struct can_frame, when used as a CAN error frame, are defined as being "controller specific". Device specific behaviours are problematic because it prevents someone from writing code which is portable between devices.
As a matter of fact, data[5] is never used, data[6] is always used to report TX error counter and data[7] is always used to report RX error counter. can-utils also relies on this.
This patch updates the comment in the uapi header to specify that data[5] is reserved (and thus should not be used) and that data[6..7] are used for error counters.
--- include/uapi/linux/can/error.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
include/uapi/linux/can/error.h +4 -1
@@ -120,6 +120,9 @@#define CAN_ERR_TRX_CANL_SHORT_TO_GND 0x70/* 0111 0000 */ #define CAN_ERR_TRX_CANL_SHORT_TO_CANH 0x80/* 1000 0000 */ -/* controller specific additional information / data[5..7] */ +/* data[5] is reserved (do not use) */ + +/* TX error counter / data[6] */ +/* RX error counter / data[7] */ #endif /* _UAPI_CAN_ERROR_H */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 360/779 can: pch_can: pch_can_error(): initialize errc before using it
In reply to Greg Kroah-HartmanFrom: Vincent Mailhol <[email protected]>
[ Upstream commit 9950f11211331180269867aef848c7cf56861742 ]
After commit 3a5c7e4611dd, the variable errc is accessed before being initialized, c.f. below W=2 warning:
| In function 'pch_can_error', | inlined from 'pch_can_poll' at drivers/net/can/pch_can.c:739:4: | drivers/net/can/pch_can.c:501:29: warning: 'errc' may be used uninitialized [-Wmaybe-uninitialized] | 501 | cf->data[6] = errc & PCH_TEC; | | ^ | drivers/net/can/pch_can.c: In function 'pch_can_poll': | drivers/net/can/pch_can.c:484:13: note: 'errc' was declared here | 484 | u32 errc, lec; | | ^~~~
Moving errc initialization up solves this issue.
--- drivers/net/can/pch_can.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/can/pch_can.c +1 -1
@@ -489,6 +489,7 @@ static void pch_can_error(struct net_device *ndev, u32 status)if (!skb)return ; + errc =ioread32 (&priv->regs->errc);if (status &PCH_BUS_OFF ) {pch_can_set_tx_all (priv,0 );pch_can_set_rx_all (priv,0 );
@@ -501,7 +502,6 @@ static void pch_can_error(struct net_device *ndev, u32 status) cf->data[7 ] = (errc &PCH_REC ) >>8 ; } - errc =ioread32 (&priv->regs->errc);/* Warning interrupt. */ if (status &PCH_EWARN ) { state =CAN_STATE_ERROR_WARNING ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 361/779 Bluetooth: hci_intel: Add check for platform_driver_register
In reply to Greg Kroah-HartmanFrom: Jiasheng Jiang <[email protected]>
[ Upstream commit ab2d2a982ff721f4b029282d9a40602ea46a745e ]
As platform_driver_register() could fail, it should be better to deal with the return value in order to maintain the code consisitency.
--- drivers/bluetooth/hci_intel.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/bluetooth/hci_intel.c +5 -1
@@ -1217,7 +1217,11 @@ static struct platform_driver intel_driver = {int __init intel_init (void ) { -platform_driver_register (&intel_driver); +int err; + + err =platform_driver_register (&intel_driver); +if (err) +return err;return hci_uart_register_proto (&intel_proto); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 362/779 i2c: cadence: Support PEC for SMBus block read
In reply to Greg Kroah-HartmanFrom: Lars-Peter Clausen <[email protected]>
[ Upstream commit 9fdf6d97f03035ad5298e2d1635036c74c2090ed ]
SMBus packet error checking (PEC) is implemented by appending one additional byte of checksum data at the end of the message. This provides additional protection and allows to detect data corruption on the I2C bus.
SMBus block reads support variable length reads. The first byte in the read message is the number of available data bytes.
The combination of PEC and block read is currently not supported by the Cadence I2C driver.
* When PEC is enabled the maximum transfer length for block reads increases from 33 to 34 bytes.
* The I2C core smbus emulation layer relies on the driver updating the i2c_msg len field with the number of received bytes. The updated length is used when checking the PEC.
Add support to the Cadence I2C driver for handling SMBus block reads with PEC. To determine the maximum transfer length uses the initial len value of the i2c_msg. When PEC is enabled this will be 2, when it is disabled it will be 1.
Once a read transfer is done also increment the len field by the amount of received data bytes.
This change has been tested with a UCM90320 PMBus power monitor, which requires block reads to access certain data fields, but also has PEC enabled by default.
--- drivers/i2c/busses/i2c-cadence.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/i2c/busses/i2c-cadence.c +9 -1
@@ -573,8 +573,13 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id) ctrl_reg =cdns_i2c_readreg (CDNS_I2C_CR_OFFSET ); ctrl_reg |=CDNS_I2C_CR_RW |CDNS_I2C_CR_CLR_FIFO ; +/* +* Receive up to I2C_SMBUS_BLOCK_MAX data bytes, plus one message length +* byte, plus one checksum byte if PEC is enabled. p_msg->len will be 2 if +* PEC is enabled, otherwise 1. +*/ if (id->p_msg->flags &I2C_M_RECV_LEN ) - id->recv_count =I2C_SMBUS_BLOCK_MAX +1 ; + id->recv_count =I2C_SMBUS_BLOCK_MAX + id->p_msg->len; id->curr_recv_count = id->recv_count;
@@ -789,6 +794,9 @@ static int cdns_i2c_process_msg(struct cdns_i2c *id, struct i2c_msg *msg,if (id->err_status &CDNS_I2C_IXR_ARB_LOST )return -EAGAIN ; +if (msg->flags &I2C_M_RECV_LEN ) + msg->len += min_t(unsigned int, msg->buf[0], I2C_SMBUS_BLOCK_MAX); +return 0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 363/779 i2c: mux-gpmux: Add of_node_put() when breaking out of loop
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 6435319c34704994e19b0767f6a4e6f37439867b ]
In i2c_mux_probe(), we should call of_node_put() when breaking out of for_each_child_of_node() which will automatically increase and decrease the refcount.
--- drivers/i2c/muxes/i2c-mux-gpmux.c | 1 + 1 file changed, 1 insertion(+)
drivers/i2c/muxes/i2c-mux-gpmux.c +1 -0
@@ -134,6 +134,7 @@ static int i2c_mux_probe(struct platform_device *pdev)return 0 ; err_children: +of_node_put (child);i2c_mux_del_adapters (muxc); err_parent:i2c_put_adapter (parent);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 364/779 wifi: wil6210: debugfs: fix uninitialized variable use in `wil_write_file_wmi()`
In reply to Greg Kroah-HartmanFrom: Ammar Faizi <[email protected]>
[ Upstream commit d578e0af3a003736f6c440188b156483d451b329 ]
Commit 7a4836560a61 changes simple_write_to_buffer() with memdup_user() but it forgets to change the value to be returned that came from simple_write_to_buffer() call. It results in the following warning:
warning: variable 'rc' is uninitialized when used here [-Wuninitialized]
return rc;
^~Remove rc variable and just return the passed in length if the memdup_user() succeeds.
--- drivers/net/wireless/ath/wil6210/debugfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/wil6210/debugfs.c +2 -2
@@ -1010,7 +1010,7 @@ static ssize_t wil_write_file_wmi(struct file *file, const char __user *buf,void *cmd;int cmdlen = len -sizeof (struct wmi_cmd_hdr );u16 cmdid; -int rc, rc1; +int rc1;if (cmdlen <0 || *ppos !=0 )return -EINVAL ;
@@ -1027,7 +1027,7 @@ static ssize_t wil_write_file_wmi(struct file *file, const char __user *buf,wil_info (wil,"0x%04x[%d] -> %d\n" , cmdid, cmdlen, rc1); -return rc; +return len; }static const struct file_operations fops_wmi = {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 365/779 wifi: iwlwifi: mvm: fix double list_add at iwl_mvm_mac_wake_tx_queue
In reply to Greg Kroah-HartmanFrom: Jose Ignacio Tornos Martinez <[email protected]>
[ Upstream commit 14a3aacf517a9de725dd3219dbbcf741e31763c4 ]
After successfull station association, if station queues are disabled for some reason, the related lists are not emptied. So if some new element is added to the list in iwl_mvm_mac_wake_tx_queue, it can match with the old one and produce a BUG like this:
[ 46.535263] list_add corruption. prev->next should be next (ffff94c1c318a360), but was 0000000000000000. (prev=ffff94c1d02d3388). [ 46.535283] ------------[ cut here ]------------ [ 46.535284] kernel BUG at lib/list_debug.c:26! [ 46.535290] invalid opcode: 0000 [#1] PREEMPT SMP PTI [ 46.585304] CPU: 0 PID: 623 Comm: wpa_supplicant Not tainted 5.19.0-rc3+ #1 [ 46.592380] Hardware name: Dell Inc. Inspiron 660s/0478VN , BIOS A07 08/24/2012 [ 46.600336] RIP: 0010:__list_add_valid.cold+0x3d/0x3f [ 46.605475] Code: f2 4c 89 c1 48 89 fe 48 c7 c7 c8 40 67 93 e8 20 cc fd ff 0f 0b 48 89 d1 4c 89 c6 4c 89 ca 48 c7 c7 70 40 67 93 e8 09 cc fd ff <0f> 0b 48 89 fe 48 c7 c7 00 41 67 93 e8 f8 cb fd ff 0f 0b 48 89 d1 [ 46.624469] RSP: 0018:ffffb20800ab76d8 EFLAGS: 00010286 [ 46.629854] RAX: 0000000000000075 RBX: ffff94c1c318a0e0 RCX: 0000000000000000 [ 46.637105] RDX: 0000000000000201 RSI: ffffffff9365e100 RDI: 00000000ffffffff [ 46.644356] RBP: ffff94c1c5f43370 R08: 0000000000000075 R09: 3064316334396666 [ 46.651607] R10: 3364323064316334 R11: 39666666663d7665 R12: ffff94c1c5f43388 [ 46.658857] R13: ffff94c1d02d3388 R14: ffff94c1c318a360 R15: ffff94c1cf2289c0 [ 46.666108] FS: 00007f65634ff7c0(0000) GS:ffff94c1da200000(0000) knlGS:0000000000000000 [ 46.674331] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 46.680170] CR2: 00007f7dfe984460 CR3: 000000010e894003 CR4: 00000000000606f0 [ 46.687422] Call Trace: [ 46.689906] <TASK> [ 46.691950] iwl_mvm_mac_wake_tx_queue+0xec/0x15c [iwlmvm] [ 46.697601] ieee80211_queue_skb+0x4b3/0x720 [mac80211] [ 46.702973] ? sta_info_get+0x46/0x60 [mac80211] [ 46.707703] ieee80211_tx+0xad/0x110 [mac80211] [ 46.712355] __ieee80211_tx_skb_tid_band+0x71/0x90 [mac80211]
...
In order to avoid this problem, we must also remove the related lists when station queues are disabled.
--- drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/wireless/intel/iwlwifi/mvm/sta.c +1 -0
@@ -1794,6 +1794,7 @@ static void iwl_mvm_disable_sta_queues(struct iwl_mvm *mvm,iwl_mvm_txq_from_mac80211 (sta->txq[i]); mvmtxq->txq_id =IWL_MVM_INVALID_QUEUE ; +list_del_init (&mvmtxq->list); } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 366/779 wifi: libertas: Fix possible refcount leak in if_usb_probe()
In reply to Greg Kroah-HartmanFrom: Hangyu Hua <[email protected]>
[ Upstream commit 6fd57e1d120bf13d4dc6c200a7cf914e6347a316 ]
usb_get_dev will be called before lbs_get_firmware_async which means that usb_put_dev need to be called when lbs_get_firmware_async fails.
--- drivers/net/wireless/marvell/libertas/if_usb.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/wireless/marvell/libertas/if_usb.c +1 -0
@@ -287,6 +287,7 @@ static int if_usb_probe(struct usb_interface *intf,return 0 ; err_get_fw: +usb_put_dev (udev);lbs_remove_card (priv); err_add_card:if_usb_reset_device (cardp);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 367/779 media: cedrus: hevc: Add check for invalid timestamp
In reply to Greg Kroah-HartmanFrom: Jernej Skrabec <[email protected]>
[ Upstream commit 143201a6435bf65f0115435e9dc6d95c66b908e9 ]
Not all DPB entries will be used most of the time. Unused entries will thus have invalid timestamps. They will produce negative buffer index which is not specifically handled. This works just by chance in current code. It will even produce bogus pointer, but since it's not used, it won't do any harm.
Let's fix that brittle design by skipping writing DPB entry altogether if timestamp is invalid.
--- drivers/staging/media/sunxi/cedrus/cedrus_h265.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/staging/media/sunxi/cedrus/cedrus_h265.c +3 -0
@@ -147,6 +147,9 @@ static void cedrus_h265_frame_info_write_dpb(struct cedrus_ctx *ctx, dpb[i].pic_order_cnt[1] }; +if (buffer_index <0 ) +continue ; +cedrus_h265_frame_info_write_single (ctx, i, dpb[i].field_pic, pic_order_cnt, buffer_index);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 368/779 net/mlx5e: Remove WARN_ON when trying to offload an unsupported TLS cipher/version
In reply to Greg Kroah-HartmanFrom: Gal Pressman <[email protected]>
[ Upstream commit 115d9f95ea7ab780ef315dc356bebba2e07cb731 ]
The driver reports whether TX/RX TLS device offloads are supported, but not which ciphers/versions, these should be handled by returning -EOPNOTSUPP when .tls_dev_add() is called.
Remove the WARN_ON kernel trace when the driver gets a request to offload a cipher/version that is not supported as it is expected.
--- drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c +1 -1
@@ -16,7 +16,7 @@ static int mlx5e_ktls_add(struct net_device *netdev, struct sock *sk,struct mlx5_core_dev *mdev = priv->mdev;int err; -if (WARN_ON (!mlx5e_ktls_type_check (mdev, crypto_info))) +if (!mlx5e_ktls_type_check (mdev, crypto_info))return -EOPNOTSUPP ;if (direction ==TLS_OFFLOAD_CTX_DIR_TX )
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 369/779 net/mlx5e: Fix the value of MLX5E_MAX_RQ_NUM_MTTS
In reply to Greg Kroah-HartmanFrom: Maxim Mikityanskiy <[email protected]>
[ Upstream commit 562696c3c62c7c23dd896e9447252ce9268cb812 ]
MLX5E_MAX_RQ_NUM_MTTS should be the maximum value, so that MLX5_MTT_OCTW(MLX5E_MAX_RQ_NUM_MTTS) fits into u16. The current value of 1 << 17 results in MLX5_MTT_OCTW(1 << 17) = 1 << 16, which doesn't fit into u16. This commit replaces it with the maximum value that still fits u16.
--- drivers/net/ethernet/mellanox/mlx5/core/en.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/en.h +1 -1
@@ -103,7 +103,7 @@ struct page_pool;#define MLX5E_REQUIRED_WQE_MTTS (MLX5_ALIGN_MTTS(MLX5_MPWRQ_PAGES_PER_WQE + 1))#define MLX5E_REQUIRED_MTTS (wqes) (wqes * MLX5E_REQUIRED_WQE_MTTS)#define MLX5E_MAX_RQ_NUM_MTTS \ - ((1 << 16) * 2)/* So that MLX5_MTT_OCTW(num_mtts) fits into u16 */ + (ALIGN_DOWN(U16_MAX, 4) * 2)/* So that MLX5_MTT_OCTW(num_mtts) fits into u16 */ #define MLX5E_ORDER2_MAX_PACKET_MTU (order_base_2(10 * 1024))#define MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE_MPW \ (ilog2(MLX5E_MAX_RQ_NUM_MTTS / MLX5E_REQUIRED_WQE_MTTS))
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 370/779 net/mlx5: Adjust log_max_qp to be 18 at most
In reply to Greg Kroah-HartmanFrom: Maher Sanalla <[email protected]>
[ Upstream commit a6e9085d791f8306084fd5bc44dd3fdd4e1ac27b ]
The cited commit limited log_max_qp to be 17 due to FW capabilities. Recently, it turned out that there are old FW versions that supported more than 17, so the cited commit caused a degradation.
Thus, set the maximum log_max_qp back to 18 as it was before the cited commit.
--- drivers/net/ethernet/mellanox/mlx5/core/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/main.c +1 -1
@@ -516,7 +516,7 @@ static int handle_hca_cap(struct mlx5_core_dev *dev, void *set_ctx)/* Check log_max_qp from HCA caps to set in current profile */ if (prof->log_max_qp ==LOG_MAX_SUPPORTED_QPS ) { - prof->log_max_qp =min_t (u8,17 ,MLX5_CAP_GEN_MAX (dev, log_max_qp)); + prof->log_max_qp =min_t (u8,18 ,MLX5_CAP_GEN_MAX (dev, log_max_qp)); }else if (MLX5_CAP_GEN_MAX (dev, log_max_qp) < prof->log_max_qp) { mlx5_core_warn(dev, "log_max_qp value in current profile is %d, changing it to HCA capability limit (%d)\n", prof->log_max_qp,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 371/779 crypto: hisilicon/hpre - dont use GFP_KERNEL to alloc mem during softirq
In reply to Greg Kroah-HartmanFrom: Zhengchao Shao <[email protected]>
[ Upstream commit 98dfa9343f37bdd4112966292751e3a93aaf2e56 ]
The hpre encryption driver may be used to encrypt and decrypt packets during the rx softirq, it is not allowed to use GFP_KERNEL.
--- drivers/crypto/hisilicon/hpre/hpre_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/crypto/hisilicon/hpre/hpre_crypto.c +1 -1
@@ -252,7 +252,7 @@ static int hpre_prepare_dma_buf(struct hpre_asym_request *hpre_req,if (unlikely (shift <0 ))return -EINVAL ; - ptr =dma_alloc_coherent (dev, ctx->key_sz, tmp,GFP_KERNEL ); + ptr =dma_alloc_coherent (dev, ctx->key_sz, tmp,GFP_ATOMIC );if (unlikely (!ptr))return -ENOMEM ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 372/779 crypto: inside-secure - Add missing MODULE_DEVICE_TABLE for of
In reply to Greg Kroah-HartmanFrom: Pali Rohár <[email protected]>
[ Upstream commit fa4d57b85786ec0e16565c75a51c208834b0c24d ]
Without MODULE_DEVICE_TABLE, crypto_safexcel.ko module is not automatically loaded on platforms where inside-secure crypto HW is specified in device tree (e.g. Armada 3720). So add missing MODULE_DEVICE_TABLE for of.
--- drivers/crypto/inside-secure/safexcel.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/crypto/inside-secure/safexcel.c +2 -0
@@ -1831,6 +1831,8 @@ static const struct of_device_id safexcel_of_match_table[] = { {}, }; +MODULE_DEVICE_TABLE (of, safexcel_of_match_table); +static struct platform_driver crypto_safexcel = { .probe = safexcel_probe, .remove = safexcel_remove,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 373/779 crypto: hisilicon/sec - fix auth key size error
In reply to Greg Kroah-HartmanFrom: Kai Ye <[email protected]>
[ Upstream commit 45f5d0176d8426cc1ab0bab84fbd8ef5c57526c6 ]
The authentication algorithm supports a maximum of 128-byte keys. The allocated key memory is insufficient.
--- drivers/crypto/hisilicon/sec2/sec_crypto.c | 6 +++--- drivers/crypto/hisilicon/sec2/sec_crypto.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-)
drivers/crypto/hisilicon/sec2/sec_crypto.c +3 -3
@@ -617,7 +617,7 @@ static int sec_auth_init(struct sec_ctx *ctx) {struct sec_auth_ctx *a_ctx = &ctx->a_ctx; - a_ctx->a_key =dma_alloc_coherent (ctx->dev,SEC_MAX_KEY_SIZE , + a_ctx->a_key =dma_alloc_coherent (ctx->dev,SEC_MAX_AKEY_SIZE , &a_ctx->a_key_dma,GFP_KERNEL );if (!a_ctx->a_key)return -ENOMEM ;
@@ -629,8 +629,8 @@ static void sec_auth_uninit(struct sec_ctx *ctx) {struct sec_auth_ctx *a_ctx = &ctx->a_ctx; -memzero_explicit (a_ctx->a_key,SEC_MAX_KEY_SIZE ); -dma_free_coherent (ctx->dev,SEC_MAX_KEY_SIZE , +memzero_explicit (a_ctx->a_key,SEC_MAX_AKEY_SIZE ); +dma_free_coherent (ctx->dev,SEC_MAX_AKEY_SIZE , a_ctx->a_key, a_ctx->a_key_dma); }
drivers/crypto/hisilicon/sec2/sec_crypto.h +1 -0
@@ -7,6 +7,7 @@#define SEC_AIV_SIZE 12#define SEC_IV_SIZE 24#define SEC_MAX_KEY_SIZE 64 +#define SEC_MAX_AKEY_SIZE 128#define SEC_COMM_SCENE 0#define SEC_MIN_BLOCK_SZ 1
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 374/779 inet: add READ_ONCE(sk->sk_bound_dev_if) in INET_MATCH()
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 4915d50e300e96929d2462041d6f6c6f061167fd ]
INET_MATCH() runs without holding a lock on the socket.
We probably need to annotate most reads.
This patch makes INET_MATCH() an inline function to ease our changes.
v2:
We remove the 32bit version of it, as modern compilers should generate the same code really, no need to try to be smarter.
Also make 'struct net *net' the first argument.
--- include/net/inet_hashtables.h | 35 ++++++++++++++++------------------- include/net/sock.h | 3 --- net/ipv4/inet_hashtables.c | 15 +++++---------- net/ipv4/udp.c | 3 +-- 4 files changed, 22 insertions(+), 34 deletions(-)
include/net/inet_hashtables.h +16 -19
@@ -295,7 +295,6 @@ static inline struct sock *inet_lookup_listener(struct net *net, ((__force __portpair)(((__u32)(__dport) << 16) | (__force __u32)(__be16)(__sport)))#endif -#if (BITS_PER_LONG ==64 )#ifdef __BIG_ENDIAN#define INET_ADDR_COOKIE (__name, __saddr, __daddr) \ const __addrpair __name = (__force __addrpair) ( \
@@ -307,24 +306,22 @@ static inline struct sock *inet_lookup_listener(struct net *net, (((__force __u64)(__be32)(__daddr)) << 32) | \ ((__force __u64)(__be32)(__saddr)))#endif /* __BIG_ENDIAN */ -#define INET_MATCH (__sk, __net, __cookie, __saddr, __daddr, __ports, __dif, __sdif) \ - (((__sk)->sk_portpair == (__ports)) && \ - ((__sk)->sk_addrpair == (__cookie)) && \ - (((__sk)->sk_bound_dev_if == (__dif)) || \ - ((__sk)->sk_bound_dev_if == (__sdif))) && \ - net_eq(sock_net(__sk), (__net))) -#else /* 32-bit arch */ -#define INET_ADDR_COOKIE (__name, __saddr, __daddr) \ - const int __name __deprecated __attribute__((unused)) - -#define INET_MATCH (__sk, __net, __cookie, __saddr, __daddr, __ports, __dif, __sdif) \ - (((__sk)->sk_portpair == (__ports)) && \ - ((__sk)->sk_daddr == (__saddr)) && \ - ((__sk)->sk_rcv_saddr == (__daddr)) && \ - (((__sk)->sk_bound_dev_if == (__dif)) || \ - ((__sk)->sk_bound_dev_if == (__sdif))) && \ - net_eq(sock_net(__sk), (__net))) -#endif /* 64-bit arch */ + +static inline bool INET_MATCH (struct net *net,const struct sock *sk, +const __addrpair cookie,const __portpair ports, +int dif,int sdif) +{ +int bound_dev_if; + +if (!net_eq (sock_net (sk), net) || + sk->sk_portpair != ports || + sk->sk_addrpair != cookie) +return false; + +/* Paired with WRITE_ONCE() from sock_bindtoindex_locked() */ + bound_dev_if =READ_ONCE (sk->sk_bound_dev_if); +return bound_dev_if == dif || bound_dev_if == sdif; +}/* Sockets in TCP_CLOSE state are _always_ taken out of the hash, so we need * not check it for lookups anymore, thanks Alexey. -DaveM
include/net/sock.h +0 -3
@@ -161,9 +161,6 @@ typedef __u64 __bitwise __addrpair;* for struct sock and struct inet_timewait_sock. */ struct sock_common { - /* skc_daddr and skc_rcv_saddr must be grouped on a 8 bytes aligned - * address on 64bit arches : cf INET_MATCH() - */ union { __addrpair skc_addrpair; struct {
net/ipv4/inet_hashtables.c +5 -10
@@ -410,13 +410,11 @@ struct sock *__inet_lookup_established(struct net *net,sk_nulls_for_each_rcu (sk, node, &head->chain) {if (sk->sk_hash != hash)continue ; -if (likely (INET_MATCH (sk, net, acookie, - saddr, daddr, ports, dif, sdif))) { +if (likely (INET_MATCH (net, sk, acookie, ports, dif, sdif))) {if (unlikely (!refcount_inc_not_zero (&sk->sk_refcnt))) goto out; -if (unlikely (!INET_MATCH (sk, net, acookie, - saddr, daddr, ports, - dif, sdif))) { +if (unlikely (!INET_MATCH (net, sk, acookie, + ports, dif, sdif))) {sock_gen_put (sk); goto begin; }
@@ -465,8 +463,7 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row,if (sk2->sk_hash != hash)continue ; -if (likely (INET_MATCH (sk2, net, acookie, - saddr, daddr, ports, dif, sdif))) { +if (likely (INET_MATCH (net, sk2, acookie, ports, dif, sdif))) {if (sk2->sk_state ==TCP_TIME_WAIT ) { tw =inet_twsk (sk2);if (twsk_unique (sk, sk2, twp))
@@ -532,9 +529,7 @@ static bool inet_ehash_lookup_by_sk(struct sock *sk,if (esk->sk_hash != sk->sk_hash)continue ;if (sk->sk_family ==AF_INET ) { -if (unlikely (INET_MATCH (esk, net, acookie, - sk->sk_daddr, - sk->sk_rcv_saddr, +if (unlikely (INET_MATCH (net, esk, acookie, ports, dif, sdif))) {return true; }
net/ipv4/udp.c +1 -2
@@ -2554,8 +2554,7 @@ static struct sock *__udp4_lib_demux_lookup(struct net *net,struct sock *sk;udp_portaddr_for_each_entry_rcu (sk, &hslot2->head) { -if (INET_MATCH (sk, net, acookie, rmt_addr, - loc_addr, ports, dif, sdif)) +if (INET_MATCH (net, sk, acookie, ports, dif, sdif))return sk;/* Only check first socket in chain */ break ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 375/779 ipv6: add READ_ONCE(sk->sk_bound_dev_if) in INET6_MATCH()
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 5d368f03280d3678433a7f119efe15dfbbb87bc8 ]
INET6_MATCH() runs without holding a lock on the socket.
We probably need to annotate most reads.
This patch makes INET6_MATCH() an inline function to ease our changes.
v2: inline function only defined if IS_ENABLED(CONFIG_IPV6)
Change the name to inet6_match(), this is no longer a macro.
--- include/net/inet6_hashtables.h | 28 +++++++++++++++++++--------- net/ipv4/inet_hashtables.c | 2 +- net/ipv6/inet6_hashtables.c | 6 +++--- net/ipv6/udp.c | 2 +- 4 files changed, 24 insertions(+), 14 deletions(-)
include/net/inet6_hashtables.h +19 -9
@@ -103,15 +103,25 @@ struct sock *inet6_lookup(struct net *net, struct inet_hashinfo *hashinfo, const int dif);int inet6_hash (struct sock *sk); -#endif /* IS_ENABLED(CONFIG_IPV6) */ -#define INET6_MATCH (__sk, __net, __saddr, __daddr, __ports, __dif, __sdif) \ - (((__sk)->sk_portpair == (__ports)) && \ - ((__sk)->sk_family == AF_INET6) && \ - ipv6_addr_equal(&(__sk)->sk_v6_daddr, (__saddr)) && \ - ipv6_addr_equal(&(__sk)->sk_v6_rcv_saddr, (__daddr)) && \ - (((__sk)->sk_bound_dev_if == (__dif)) || \ - ((__sk)->sk_bound_dev_if == (__sdif))) && \ - net_eq(sock_net(__sk), (__net))) +static inline bool inet6_match (struct net *net,const struct sock *sk, +const struct in6_addr *saddr, +const struct in6_addr *daddr, +const __portpair ports, +const int dif,const int sdif) +{ +int bound_dev_if; + +if (!net_eq (sock_net (sk), net) || + sk->sk_family !=AF_INET6 || + sk->sk_portpair != ports || + !ipv6_addr_equal (&sk->sk_v6_daddr, saddr) || + !ipv6_addr_equal (&sk->sk_v6_rcv_saddr, daddr)) +return false; + + bound_dev_if =READ_ONCE (sk->sk_bound_dev_if); +return bound_dev_if == dif || bound_dev_if == sdif; +} +#endif /* IS_ENABLED(CONFIG_IPV6) */ #endif /* _INET6_HASHTABLES_H */
net/ipv4/inet_hashtables.c +1 -1
@@ -536,7 +536,7 @@ static bool inet_ehash_lookup_by_sk(struct sock *sk, }#if IS_ENABLED (CONFIG_IPV6 ) else if (sk->sk_family == AF_INET6) { -if (unlikely (INET6_MATCH (esk, net, +if (unlikely (inet6_match (net, esk, &sk->sk_v6_daddr, &sk->sk_v6_rcv_saddr, ports, dif, sdif))) {
net/ipv6/inet6_hashtables.c +3 -3
@@ -71,12 +71,12 @@ struct sock *__inet6_lookup_established(struct net *net,sk_nulls_for_each_rcu (sk, node, &head->chain) {if (sk->sk_hash != hash)continue ; -if (!INET6_MATCH (sk, net, saddr, daddr, ports, dif, sdif)) +if (!inet6_match (net, sk, saddr, daddr, ports, dif, sdif))continue ;if (unlikely (!refcount_inc_not_zero (&sk->sk_refcnt))) goto out; -if (unlikely (!INET6_MATCH (sk, net, saddr, daddr, ports, dif, sdif))) { +if (unlikely (!inet6_match (net, sk, saddr, daddr, ports, dif, sdif))) {sock_gen_put (sk); goto begin; }
@@ -269,7 +269,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,if (sk2->sk_hash != hash)continue ; -if (likely (INET6_MATCH (sk2, net, saddr, daddr, ports, +if (likely (inet6_match (net, sk2, saddr, daddr, ports, dif, sdif))) {if (sk2->sk_state ==TCP_TIME_WAIT ) { tw =inet_twsk (sk2);
net/ipv6/udp.c +1 -1
@@ -1035,7 +1035,7 @@ static struct sock *__udp6_lib_demux_lookup(struct net *net,udp_portaddr_for_each_entry_rcu (sk, &hslot2->head) {if (sk->sk_state ==TCP_ESTABLISHED && -INET6_MATCH (sk, net, rmt_addr, loc_addr, ports, dif, sdif)) +inet6_match (net, sk, rmt_addr, loc_addr, ports, dif, sdif))return sk;/* Only check first socket in chain */ break ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 376/779 net: allow unbound socket for packets in VRF when tcp_l3mdev_accept set
In reply to Greg Kroah-HartmanFrom: Mike Manning <[email protected]>
[ Upstream commit 944fd1aeacb627fa617f85f8e5a34f7ae8ea4d8e ]
The commit 3c82a21f4320 ("net: allow binding socket in a VRF when there's an unbound socket") changed the inet socket lookup to avoid packets in a VRF from matching an unbound socket. This is to ensure the necessary isolation between the default and other VRFs for routing and forwarding. VRF-unaware processes running in the default VRF cannot access another VRF and have to be run with 'ip vrf exec <vrf>'. This is to be expected with tcp_l3mdev_accept disabled, but could be reallowed when this sysctl option is enabled. So instead of directly checking dif and sdif in inet[6]_match, here call inet_sk_bound_dev_eq(). This allows a match on unbound socket for non-zero sdif i.e. for packets in a VRF, if tcp_l3mdev_accept is enabled.
--- include/net/inet6_hashtables.h | 7 +++---- include/net/inet_hashtables.h | 19 +++---------------- include/net/inet_sock.h | 11 +++++++++++ 3 files changed, 17 insertions(+), 20 deletions(-)
include/net/inet6_hashtables.h +3 -4
@@ -110,8 +110,6 @@ static inline bool inet6_match(struct net *net, const struct sock *sk,const __portpair ports, const int dif, const int sdif) { - int bound_dev_if; - if (!net_eq(sock_net(sk), net) || sk->sk_family != AF_INET6 || sk->sk_portpair != ports ||
@@ -119,8 +117,9 @@ static inline bool inet6_match(struct net *net, const struct sock *sk, !ipv6_addr_equal(&sk->sk_v6_rcv_saddr, daddr))return false; - bound_dev_if =READ_ONCE (sk->sk_bound_dev_if); - return bound_dev_if == dif || bound_dev_if == sdif; +/* READ_ONCE() paired with WRITE_ONCE() in sock_bindtoindex_locked() */ +return inet_sk_bound_dev_eq (net,READ_ONCE (sk->sk_bound_dev_if), dif, + sdif); }#endif /* IS_ENABLED(CONFIG_IPV6) */
include/net/inet_hashtables.h +3 -16
@@ -203,17 +203,6 @@ static inline void inet_ehash_locks_free(struct inet_hashinfo *hashinfo) hashinfo->ehash_locks =NULL ; } -static inline bool inet_sk_bound_dev_eq (struct net *net,int bound_dev_if, -int dif,int sdif) -{ -#if IS_ENABLED (CONFIG_NET_L3_MASTER_DEV ) -return inet_bound_dev_eq (!!READ_ONCE (net->ipv4.sysctl_tcp_l3mdev_accept), - bound_dev_if, dif, sdif); -#else -return inet_bound_dev_eq (true, bound_dev_if, dif, sdif); -#endif -} -struct inet_bind_bucket * inet_bind_bucket_create(struct kmem_cache *cachep, struct net *net, struct inet_bind_hashbucket *head,
@@ -311,16 +300,14 @@ static inline bool INET_MATCH(struct net *net, const struct sock *sk, const __addrpair cookie, const __portpair ports, int dif, int sdif) { - int bound_dev_if; - if (!net_eq(sock_net(sk), net) || sk->sk_portpair != ports || sk->sk_addrpair != cookie) return false; -/* Paired with WRITE_ONCE() from sock_bindtoindex_locked() */ - bound_dev_if =READ_ONCE (sk->sk_bound_dev_if); -return bound_dev_if == dif || bound_dev_if == sdif; +/* READ_ONCE() paired with WRITE_ONCE() in sock_bindtoindex_locked() */ +return inet_sk_bound_dev_eq (net,READ_ONCE (sk->sk_bound_dev_if), dif, + sdif); }/* Sockets in TCP_CLOSE state are _always_ taken out of the hash, so we need
include/net/inet_sock.h +11 -0
@@ -149,6 +149,17 @@ static inline bool inet_bound_dev_eq(bool l3mdev_accept, int bound_dev_if,return bound_dev_if == dif || bound_dev_if == sdif; } +static inline bool inet_sk_bound_dev_eq (struct net *net,int bound_dev_if, +int dif,int sdif) +{ +#if IS_ENABLED (CONFIG_NET_L3_MASTER_DEV ) +return inet_bound_dev_eq (!!READ_ONCE (net->ipv4.sysctl_tcp_l3mdev_accept), + bound_dev_if, dif, sdif); +#else +return inet_bound_dev_eq (true, bound_dev_if, dif, sdif); +#endif +} +struct inet_cork {unsigned int flags;__be32 addr;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 377/779 netdevsim: fib: Fix reference count leak on route deletion failure
In reply to Greg Kroah-HartmanFrom: Ido Schimmel <[email protected]>
[ Upstream commit 180a6a3ee60a7cb69ed1232388460644f6a21f00 ]
As part of FIB offload simulation, netdevsim stores IPv4 and IPv6 routes and holds a reference on FIB info structures that in turn hold a reference on the associated nexthop device(s).
In the unlikely case where we are unable to allocate memory to process a route deletion request, netdevsim will not release the reference from the associated FIB info structure, thereby preventing the associated nexthop device(s) from ever being removed [1].
Fix this by scheduling a work item that will flush netdevsim's FIB table upon route deletion failure. This will cause netdevsim to release its reference from all the FIB info structures in its table.
Reported by Lucas Leong of Trend Micro Zero Day Initiative.
--- drivers/net/netdevsim/fib.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-)
drivers/net/netdevsim/fib.c +26 -1
@@ -53,6 +53,7 @@ struct nsim_fib_data {struct rhashtable nexthop_ht;struct devlink *devlink;struct work_struct fib_event_work; +struct work_struct fib_flush_work;struct list_head fib_event_queue;spinlock_t fib_event_queue_lock;/* Protects fib event queue list */ struct mutex nh_lock;/* Protects NH HT */
@@ -977,7 +978,7 @@ static int nsim_fib_event_schedule_work(struct nsim_fib_data *data, fib_event =kzalloc (sizeof (*fib_event),GFP_ATOMIC );if (!fib_event) -return NOTIFY_BAD ; + goto err_fib_event_alloc; fib_event->data = data; fib_event->event = event;
@@ -1005,6 +1006,9 @@ static int nsim_fib_event_schedule_work(struct nsim_fib_data *data, err_fib_prepare_event:kfree (fib_event); +err_fib_event_alloc: +if (event ==FIB_EVENT_ENTRY_DEL ) +schedule_work (&data->fib_flush_work);return NOTIFY_BAD ; }
@@ -1482,6 +1486,24 @@ static void nsim_fib_event_work(struct work_struct *work)mutex_unlock (&data->fib_lock); } +static void nsim_fib_flush_work (struct work_struct *work) +{ + struct nsim_fib_data *data = container_of(work, struct nsim_fib_data, + fib_flush_work); +struct nsim_fib_rt *fib_rt, *fib_rt_tmp; + +/* Process pending work. */ +flush_work (&data->fib_event_work); + +mutex_lock (&data->fib_lock); +list_for_each_entry_safe (fib_rt, fib_rt_tmp, &data->fib_rt_list, list) { +rhashtable_remove_fast (&data->fib_rt_ht, &fib_rt->ht_node, + nsim_fib_rt_ht_params); +nsim_fib_rt_free (fib_rt, data); + } +mutex_unlock (&data->fib_lock); +} +static int nsim_fib_debugfs_init (struct nsim_fib_data *data,struct nsim_dev *nsim_dev) {
@@ -1540,6 +1562,7 @@ struct nsim_fib_data *nsim_fib_create(struct devlink *devlink, goto err_rhashtable_nexthop_destroy;INIT_WORK (&data->fib_event_work, nsim_fib_event_work); +INIT_WORK (&data->fib_flush_work, nsim_fib_flush_work);INIT_LIST_HEAD (&data->fib_event_queue);spin_lock_init (&data->fib_event_queue_lock);
@@ -1586,6 +1609,7 @@ struct nsim_fib_data *nsim_fib_create(struct devlink *devlink, err_nexthop_nb_unregister:unregister_nexthop_notifier (devlink_net (devlink), &data->nexthop_nb); err_rhashtable_fib_destroy: +cancel_work_sync (&data->fib_flush_work);flush_work (&data->fib_event_work);rhashtable_free_and_destroy (&data->fib_rt_ht, nsim_fib_rt_free, data);
@@ -1615,6 +1639,7 @@ void nsim_fib_destroy(struct devlink *devlink, struct nsim_fib_data *data) NSIM_RESOURCE_IPV4_FIB);unregister_fib_notifier (devlink_net (devlink), &data->fib_nb);unregister_nexthop_notifier (devlink_net (devlink), &data->nexthop_nb); +cancel_work_sync (&data->fib_flush_work);flush_work (&data->fib_event_work);rhashtable_free_and_destroy (&data->fib_rt_ht, nsim_fib_rt_free, data);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 378/779 wifi: rtw88: check the return value of alloc_workqueue()
In reply to Greg Kroah-HartmanFrom: William Dean <[email protected]>
[ Upstream commit 42bbf810e155efc6129a3a648ae5300f00b79d7b ]
The function alloc_workqueue() in rtw_core_init() can fail, but there is no check of its return value. To fix this bug, its return value should be checked with new error handling code.
--- drivers/net/wireless/realtek/rtw88/main.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/net/wireless/realtek/rtw88/main.c +4 -0
@@ -1819,6 +1819,10 @@ int rtw_core_init(struct rtw_dev *rtwdev)timer_setup (&rtwdev->tx_report.purge_timer, rtw_tx_report_purge_timer,0 ); rtwdev->tx_wq =alloc_workqueue ("rtw_tx_wq" ,WQ_UNBOUND |WQ_HIGHPRI ,0 ); +if (!rtwdev->tx_wq) { +rtw_warn (rtwdev,"alloc_workqueue rtw_tx_wq failed\n" ); +return -ENOMEM ; + }INIT_DELAYED_WORK (&rtwdev->watch_dog_work, rtw_watch_dog_work);INIT_DELAYED_WORK (&coex->bt_relink_work, rtw_coex_bt_relink_work);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 379/779 iavf: Fix max_rate limiting
In reply to Greg Kroah-HartmanFrom: Przemyslaw Patynowski <[email protected]>
[ Upstream commit ec60d54cb9a3d43a02c5612a03093c18233e6601 ]
Fix max_rate option in TC, check for proper quanta boundaries. Check for minimum value provided and if it fits expected 50Mbps quanta.
Without this patch, iavf could send settings for max_rate limiting that would be accepted from by PF even the max_rate option is less than expected 50Mbps quanta. It results in no rate limiting on traffic as rate limiting will be floored to 0.
Example:
tc qdisc add dev $vf root mqprio num_tc 3 map 0 2 1 queues \
2@0 2@2 2@4 hw 1 mode channel shaper bw_rlimit \max_rate 50Mbps 500Mbps 500Mbps
Should limit TC0 to circa 50 Mbps
tc qdisc add dev $vf root mqprio num_tc 3 map 0 2 1 queues \
2@0 2@2 2@4 hw 1 mode channel shaper bw_rlimit \max_rate 0Mbps 100Kbit 500Mbps
Should return error
--- drivers/net/ethernet/intel/iavf/iavf.h | 1 + drivers/net/ethernet/intel/iavf/iavf_main.c | 25 +++++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-)
drivers/net/ethernet/intel/iavf/iavf.h +1 -0
@@ -89,6 +89,7 @@ struct iavf_vsi {#define IAVF_HKEY_ARRAY_SIZE ((IAVF_VFQF_HKEY_MAX_INDEX + 1) * 4)#define IAVF_HLUT_ARRAY_SIZE ((IAVF_VFQF_HLUT_MAX_INDEX + 1) * 4)#define IAVF_MBPS_DIVISOR 125000/* divisor to convert to Mbps */ +#define IAVF_MBPS_QUANTA 50#define IAVF_VIRTCHNL_VF_RESOURCE_SIZE (sizeof(struct virtchnl_vf_resource) + \ (IAVF_MAX_VF_VSI * \
drivers/net/ethernet/intel/iavf/iavf_main.c +23 -2
@@ -2732,6 +2732,7 @@ static int iavf_validate_ch_config(struct iavf_adapter *adapter, struct tc_mqprio_qopt_offload *mqprio_qopt) {u64 total_max_rate =0 ; +u32 tx_rate_rem =0 ;int i, num_qps =0 ;u64 tx_rate =0 ;int ret =0 ;
@@ -2746,12 +2747,32 @@ static int iavf_validate_ch_config(struct iavf_adapter *adapter,return -EINVAL ;if (mqprio_qopt->min_rate[i]) {dev_err (&adapter->pdev->dev, -"Invalid min tx rate (greater than 0) specified\n" ); +"Invalid min tx rate (greater than 0) specified for TC%d\n" , + i);return -EINVAL ; } -/*convert to Mbps */ + +/* convert to Mbps */ tx_rate =div_u64 (mqprio_qopt->max_rate[i],IAVF_MBPS_DIVISOR ); + +if (mqprio_qopt->max_rate[i] && + tx_rate <IAVF_MBPS_QUANTA ) { +dev_err (&adapter->pdev->dev, +"Invalid max tx rate for TC%d, minimum %dMbps\n" , + i,IAVF_MBPS_QUANTA ); +return -EINVAL ; + } + + (void )div_u64_rem (tx_rate,IAVF_MBPS_QUANTA , &tx_rate_rem); + +if (tx_rate_rem !=0 ) { +dev_err (&adapter->pdev->dev, +"Invalid max tx rate for TC%d, not divisible by %d\n" , + i,IAVF_MBPS_QUANTA ); +return -EINVAL ; + } + total_max_rate += tx_rate; num_qps += mqprio_qopt->qopt.count[i]; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 380/779 iavf: Fix tc qdisc show listing too many queues
In reply to Greg Kroah-HartmanFrom: Przemyslaw Patynowski <[email protected]>
[ Upstream commit 93cb804edab1b9a5bb7bb7b6824012dbb20abf22 ]
Fix tc qdisc show dev <ethX> root displaying too many fq_codel qdiscs.tc_modify_qdisc, which is caller of ndo_setup_tc, expects driver to callnetif_set_real_num_tx_queues, which prepares qdiscs.
Without this patch, fq_codel qdiscs would not be adjusted to number of
queues on VF.
e.g.:
tc qdisc show dev <ethX>
qdisc mq 0: root
qdisc fq_codel 0: parent :4 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64 qdisc fq_codel 0: parent :3 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64 qdisc fq_codel 0: parent :2 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64 qdisc fq_codel 0: parent :1 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64 tc qdisc add dev <ethX> root mqprio num_tc 2 map 1 0 0 0 0 0 0 0 queues 1@0 1@1 hw 1 mode channel shaper bw_rlimit max_rate 5000Mbit 150Mbit tc qdisc show dev <ethX>
qdisc mqprio 8003: root tc 2 map 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
queues:(0:0) (1:1)
mode:channel
shaper:bw_rlimit max_rate:5Gbit 150Mbit
qdisc fq_codel 0: parent 8003:4 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64 qdisc fq_codel 0: parent 8003:3 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64 qdisc fq_codel 0: parent 8003:2 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64 qdisc fq_codel 0: parent 8003:1 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
While after fix:
tc qdisc add dev <ethX> root mqprio num_tc 2 map 1 0 0 0 0 0 0 0 queues 1@0 1@1 hw 1 mode channel shaper bw_rlimit max_rate 5000Mbit 150Mbit tc qdisc show dev <ethX> #should show 2, shows 4
qdisc mqprio 8004: root tc 2 map 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
queues:(0:0) (1:1)
mode:channel
shaper:bw_rlimit max_rate:5Gbit 150Mbit
qdisc fq_codel 0: parent 8004:2 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64 qdisc fq_codel 0: parent 8004:1 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
--- drivers/net/ethernet/intel/iavf/iavf.h | 5 +++++ drivers/net/ethernet/intel/iavf/iavf_main.c | 21 +++++++++++++++++++++ 2 files changed, 26 insertions(+)
drivers/net/ethernet/intel/iavf/iavf.h +5 -0
@@ -378,6 +378,11 @@ struct iavf_adapter {/* lock to protect access to the cloud filter list */ spinlock_t cloud_filter_list_lock;u16 num_cloud_filters; +/* snapshot of "num_active_queues" before setup_tc for qdisc add +* is invoked. This information is useful during qdisc del flow, +* to restore correct number of queues +*/ +int orig_num_active_queues;#define IAVF_MAX_FDIR_FILTERS 128/* max allowed Flow Director filters */ u16 fdir_active_fltr;
drivers/net/ethernet/intel/iavf/iavf_main.c +21 -0
@@ -2839,6 +2839,7 @@ static int __iavf_setup_tc(struct net_device *netdev, void *type_data)netif_tx_disable (netdev);iavf_del_all_cloud_filters (adapter); adapter->aq_required =IAVF_FLAG_AQ_DISABLE_CHANNELS ; + total_qps = adapter->orig_num_active_queues; goto exit; }else {return -EINVAL ;
@@ -2882,7 +2883,21 @@ static int __iavf_setup_tc(struct net_device *netdev, void *type_data) adapter->ch_config.ch_info[i].offset =0 ; } } + +/* Take snapshot of original config such as "num_active_queues" +* It is used later when delete ADQ flow is exercised, so that +* once delete ADQ flow completes, VF shall go back to its +* original queue configuration +*/ + + adapter->orig_num_active_queues = adapter->num_active_queues; + +/* Store queue info based on TC so that VF gets configured +* with correct number of queues when VF completes ADQ config +* flow +*/ adapter->ch_config.total_qps = total_qps; +netif_tx_stop_all_queues (netdev);netif_tx_disable (netdev); adapter->aq_required |=IAVF_FLAG_AQ_ENABLE_CHANNELS ;
@@ -2899,6 +2914,12 @@ static int __iavf_setup_tc(struct net_device *netdev, void *type_data) } } exit: +if (test_bit (__IAVF_IN_REMOVE_TASK, &adapter->crit_section)) +return 0 ; + +netif_set_real_num_rx_queues (netdev, total_qps); +netif_set_real_num_tx_queues (netdev, total_qps); +return ret; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 381/779 netdevsim: Avoid allocation warnings triggered from user space
In reply to Greg Kroah-HartmanFrom: Jakub Kicinski <[email protected]>
[ Upstream commit d0b80a9edb1a029ff913e81b47540e57ad034329 ]
We need to suppress warnings from sily map sizes. Also switch from GFP_USER to GFP_KERNEL_ACCOUNT, I'm pretty sure I misunderstood the flags when writing this code.
--- drivers/net/netdevsim/bpf.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/net/netdevsim/bpf.c +5 -3
@@ -351,10 +351,12 @@ nsim_map_alloc_elem(struct bpf_offloaded_map *offmap, unsigned int idx) {struct nsim_bpf_bound_map *nmap = offmap->dev_priv; - nmap->entry[idx].key =kmalloc (offmap->map.key_size,GFP_USER ); + nmap->entry[idx].key =kmalloc (offmap->map.key_size, +GFP_KERNEL_ACCOUNT | __GFP_NOWARN);if (!nmap->entry[idx].key)return -ENOMEM ; - nmap->entry[idx].value =kmalloc (offmap->map.value_size,GFP_USER ); + nmap->entry[idx].value =kmalloc (offmap->map.value_size, +GFP_KERNEL_ACCOUNT | __GFP_NOWARN);if (!nmap->entry[idx].value) {kfree (nmap->entry[idx].key); nmap->entry[idx].key =NULL ;
@@ -496,7 +498,7 @@ nsim_bpf_map_alloc(struct netdevsim *ns, struct bpf_offloaded_map *offmap)if (offmap->map.map_flags)return -EINVAL ; - nmap =kzalloc (sizeof (*nmap),GFP_USER ); + nmap =kzalloc (sizeof (*nmap),GFP_KERNEL_ACCOUNT );if (!nmap)return -ENOMEM ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 382/779 net: rose: fix netdev reference changes
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 931027820e4dafabc78aff82af59f8c1c4bd3128 ]
Bernard reported that trying to unload rose module would lead to infamous messages:
unregistered_netdevice: waiting for rose0 to become free. Usage count = xx
This patch solves the issue, by making sure each socket referring to a netdevice holds a reference count on it, and properly releases it in rose_release().
rose_dev_first() is also fixed to take a device reference before leaving the rcu_read_locked section.
Following patch will add ref_tracker annotations to ease future bug hunting.
--- net/rose/af_rose.c | 11 +++++++++-- net/rose/rose_route.c | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-)
net/rose/af_rose.c +9 -2
@@ -191,6 +191,7 @@ static void rose_kill_by_device(struct net_device *dev)rose_disconnect (s,ENETUNREACH ,ROSE_OUT_OF_ORDER ,0 );if (rose->neighbour) rose->neighbour->use--; +dev_put (rose->device); rose->device =NULL ; } }
@@ -591,6 +592,8 @@ static struct sock *rose_make_new(struct sock *osk) rose->idle = orose->idle; rose->defer = orose->defer; rose->device = orose->device; +if (rose->device) +dev_hold (rose->device); rose->qbitincl = orose->qbitincl;return sk;
@@ -644,6 +647,7 @@ static int rose_release(struct socket *sock)break ; } +dev_put (rose->device); sock->sk =NULL ;release_sock (sk);sock_put (sk);
@@ -720,7 +724,6 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_lestruct rose_sock *rose =rose_sk (sk);struct sockaddr_rose *addr = (struct sockaddr_rose *)uaddr;unsigned char cause, diagnostic; -struct net_device *dev;ax25_uid_assoc *user;int n, err =0 ;
@@ -777,9 +780,12 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le }if (sock_flag (sk,SOCK_ZAPPED )) {/* Must bind first - autobinding in this may or may not work */ +struct net_device *dev; +sock_reset_flag (sk,SOCK_ZAPPED ); -if ((dev =rose_dev_first ()) ==NULL ) { + dev =rose_dev_first (); +if (!dev) { err = -ENETUNREACH ; goto out_release; }
@@ -787,6 +793,7 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le user =ax25_findbyuid (current_euid ());if (!user) { err = -EINVAL ; +dev_put (dev); goto out_release; }
net/rose/rose_route.c +2 -0
@@ -615,6 +615,8 @@ struct net_device *rose_dev_first(void)if (first ==NULL ||strncmp (dev->name, first->name,3 ) <0 ) first = dev; } +if (first) +dev_hold (first);rcu_read_unlock ();return first;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 383/779 net: ionic: fix error check for vlan flags in ionic_set_nic_features()
In reply to Greg Kroah-HartmanFrom: Jian Shen <[email protected]>
[ Upstream commit a86e86db5e6d72c82724a63ca1c5293409a21518 ]
The prototype of input features of ionic_set_nic_features() is netdev_features_t, but the vlan_flags is using the private definition of ionic drivers. It should use the variable ctx.cmd.lif_setattr.features, rather than features to check the vlan flags. So fixes it.
--- drivers/net/ethernet/pensando/ionic/ionic_lif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/pensando/ionic/ionic_lif.c +1 -1
@@ -1565,7 +1565,7 @@ static int ionic_set_nic_features(struct ionic_lif *lif,if ((old_hw_features ^ lif->hw_features) &IONIC_ETH_HW_RX_HASH )ionic_lif_rss_config (lif, lif->rss_types,NULL ,NULL ); -if ((vlan_flags & features) && +if ((vlan_flags &le64_to_cpu (ctx.cmd.lif_setattr.features)) && !(vlan_flags &le64_to_cpu (ctx.comp.lif_setattr.features)))dev_info_once (lif->ionic->dev,"NIC is not supporting vlan offload, likely in SmartNIC mode\n" );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 384/779 dccp: put dccp_qpolicy_full() and dccp_qpolicy_push() in the same lock
In reply to Greg Kroah-HartmanFrom: Hangyu Hua <[email protected]>
[ Upstream commit a41b17ff9dacd22f5f118ee53d82da0f3e52d5e3 ]
In the case of sk->dccps_qpolicy == DCCPQ_POLICY_PRIO, dccp_qpolicy_full will drop a skb when qpolicy is full. And the lock in dccp_sendmsg is released before sock_alloc_send_skb and then relocked after sock_alloc_send_skb. The following conditions may lead dccp_qpolicy_push to add skb to an already full sk_write_queue:
thread1--->lock
thread1--->dccp_qpolicy_full: queue is full. drop a skb thread1--->unlock
thread2--->lock
thread2--->dccp_qpolicy_full: queue is not full. no need to drop. thread2--->unlock
thread1--->lock
thread1--->dccp_qpolicy_push: add a skb. queue is full. thread1--->unlock
thread2--->lock
thread2--->dccp_qpolicy_push: add a skb! thread2--->unlock
Fix this by moving dccp_qpolicy_full.
--- net/dccp/proto.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
net/dccp/proto.c +5 -5
@@ -747,11 +747,6 @@ int dccp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)lock_sock (sk); -if (dccp_qpolicy_full (sk)) { - rc = -EAGAIN ; - goto out_release; - } - timeo =sock_sndtimeo (sk, noblock);/*
@@ -770,6 +765,11 @@ int dccp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)if (skb ==NULL ) goto out_release; +if (dccp_qpolicy_full (sk)) { + rc = -EAGAIN ; + goto out_discard; + } +if (sk->sk_state ==DCCP_CLOSED ) { rc = -ENOTCONN ; goto out_discard;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 385/779 net: usb: make USB_RTL8153_ECM non user configurable
In reply to Greg Kroah-HartmanFrom: Maciej Żenczykowski <[email protected]>
[ Upstream commit f56530dcdb0684406661ac9f1accf48319d07600 ]
This refixes:
commit 7da17624e7948d5d9660b910f8079d26d26ce453
nt: usb: USB_RTL8153_ECM should not default to y
In general, device drivers should not be enabled by default.
which basically broke the commit it claimed to fix, ie:
commit 657bc1d10bfc23ac06d5d687ce45826c760744f9
r8153_ecm: avoid to be prior to r8152 driver
Avoid r8153_ecm is compiled as built-in, if r8152 driver is compiled as modules. Otherwise, the r8153_ecm would be used, even though the device is supported by r8152 driver.
this commit amounted to:
drivers/net/usb/Kconfig:
+config USB_RTL8153_ECM
+ tristate "RTL8153 ECM support" + depends on USB_NET_CDCETHER && (USB_RTL8152 || USB_RTL8152=n) + default y + help + This option supports ECM mode for RTL8153 ethernet adapter, when + CONFIG_USB_RTL8152 is not set, or the RTL8153 device is not + supported by r8152 driver.
drivers/net/usb/Makefile:
-obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o r8153_ecm.o +obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o +obj-$(CONFIG_USB_RTL8153_ECM) += r8153_ecm.o
And as can be seen it pulls a piece of the cdc_ether driver out into a separate config option to be able to make this piece modular in case cdc_ether is builtin, while r8152 is modular.
While in general, device drivers should indeed not be enabled by default:
this isn't a device driver per say, but rather this is support code for the CDCETHER (ECM) driver, and should thus be enabled if it is enabled.
See also email thread at:
https://www.spinics.net/lists/netdev/msg767649.html
In:
https://www.spinics.net/lists/netdev/msg768284.html
Jakub wrote:
And when we say "removed" we can just hide it from what's prompted to the user (whatever such internal options are called)? I believe this way we don't bring back Marek's complaint.
Side note: these incorrect defaults will result in Android 13 on 5.15 GKI kernels lacking USB_RTL8153_ECM support while having USB_NET_CDCETHER (luckily we also have USB_RTL8150 and USB_RTL8152, so it's probably only an issue for very new RTL815x hardware with no native 5.15 driver).
--- drivers/net/usb/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/usb/Kconfig +2 -1
@@ -636,8 +636,9 @@ config USB_NET_AQC111 * Aquantia AQtion USB to 5GbE config USB_RTL8153_ECM - tristate "RTL8153 ECM support" + tristate depends on USB_NET_CDCETHER && (USB_RTL8152 || USB_RTL8152=n) + default y help This option supports ECM mode for RTL8153 ethernet adapter, when CONFIG_USB_RTL8152 is not set, or the RTL8153 device is not
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 386/779 wireguard: ratelimiter: use hrtimer in selftest
In reply to Greg Kroah-HartmanFrom: Jason A. Donenfeld <[email protected]>
[ Upstream commit 151c8e499f4705010780189377f85b57400ccbf5 ]
Using msleep() is problematic because it's compared against ratelimiter.c's ktime_get_coarse_boottime_ns(), which means on systems with slow jiffies (such as UML's forced HZ=100), the result is inaccurate. So switch to using schedule_hrtimeout().
However, hrtimer gives us access only to the traditional posix timers, and none of the _COARSE variants. So now, rather than being too imprecise like jiffies, it's too precise.
One solution would be to give it a large "range" value, but this will still fire early on a loaded system. A better solution is to align the timeout to the actual coarse timer, and then round up to the nearest tick, plus change.
So add the timeout to the current coarse time, and then schedule_hrtimer() until the absolute computed time.
This should hopefully reduce flakes in CI as well. Note that we keep the retry loop in case the entire function is running behind, because the test could still be scheduled out, by either the kernel or by the hypervisor's kernel, in which case restarting the test and hoping to not be scheduled out still helps.
--- drivers/net/wireguard/selftest/ratelimiter.c | 25 +++++++++++--------- kernel/time/hrtimer.c | 1 + 2 files changed, 15 insertions(+), 11 deletions(-)
drivers/net/wireguard/selftest/ratelimiter.c +14 -11
@@ -6,28 +6,29 @@#ifdef DEBUG #include <linux/jiffies.h> +#include <linux/hrtimer.h> static const struct {bool result; -unsigned int msec_to_sleep_before; +u64 nsec_to_sleep_before; } expected_results[]__initconst = { [0 ...PACKETS_BURSTABLE -1 ] = { true,0 }, [PACKETS_BURSTABLE ] = { false,0 }, - [PACKETS_BURSTABLE +1 ] = { true,MSEC_PER_SEC /PACKETS_PER_SECOND }, + [PACKETS_BURSTABLE +1 ] = { true,NSEC_PER_SEC /PACKETS_PER_SECOND }, [PACKETS_BURSTABLE +2 ] = { false,0 }, - [PACKETS_BURSTABLE +3 ] = { true, (MSEC_PER_SEC /PACKETS_PER_SECOND ) *2 }, + [PACKETS_BURSTABLE +3 ] = { true, (NSEC_PER_SEC /PACKETS_PER_SECOND ) *2 }, [PACKETS_BURSTABLE +4 ] = { true,0 }, [PACKETS_BURSTABLE +5 ] = { false,0 } };static __init unsigned int maximum_jiffies_at_index (int index) { -unsigned int total_msecs =2 *MSEC_PER_SEC /PACKETS_PER_SECOND /3 ; +u64 total_nsecs =2 *NSEC_PER_SEC /PACKETS_PER_SECOND /3 ;int i;for (i =0 ; i <= index; ++i) - total_msecs += expected_results[i].msec_to_sleep_before; -return msecs_to_jiffies (total_msecs); + total_nsecs += expected_results[i].nsec_to_sleep_before; +return nsecs_to_jiffies (total_nsecs); } static __init int timings_test(struct sk_buff *skb4, struct iphdr *hdr4,
@@ -42,8 +43,12 @@ static __init int timings_test(struct sk_buff *skb4, struct iphdr *hdr4, loop_start_time = jiffies;for (i =0 ; i <ARRAY_SIZE (expected_results); ++i) { -if (expected_results[i].msec_to_sleep_before) -msleep (expected_results[i].msec_to_sleep_before); +if (expected_results[i].nsec_to_sleep_before) { +ktime_t timeout =ktime_add (ktime_add_ns (ktime_get_coarse_boottime (),TICK_NSEC *4 /3 ), +ns_to_ktime (expected_results[i].nsec_to_sleep_before)); +set_current_state (TASK_UNINTERRUPTIBLE ); +schedule_hrtimeout_range_clock (&timeout,0 ,HRTIMER_MODE_ABS ,CLOCK_BOOTTIME ); + }if (time_is_before_jiffies (loop_start_time +maximum_jiffies_at_index (i)))
@@ -127,7 +132,7 @@ bool __init wg_ratelimiter_selftest(void)if (IS_ENABLED (CONFIG_KASAN ) ||IS_ENABLED (CONFIG_UBSAN ))return true; -BUILD_BUG_ON (MSEC_PER_SEC %PACKETS_PER_SECOND !=0 ); +BUILD_BUG_ON (NSEC_PER_SEC %PACKETS_PER_SECOND !=0 );if (wg_ratelimiter_init ()) goto out;
@@ -176,7 +181,6 @@ bool __init wg_ratelimiter_selftest(void) test += test_count; goto err; } -msleep (500 );continue ; }else if (ret <0 ) { test += test_count;
@@ -195,7 +199,6 @@ bool __init wg_ratelimiter_selftest(void) test += test_count; goto err; } -msleep (50 );continue ; } test += test_count;
kernel/time/hrtimer.c +1 -0
@@ -2311,6 +2311,7 @@ schedule_hrtimeout_range_clock(ktime_t *expires, u64 delta,return !t.task ?0 : -EINTR ; } +EXPORT_SYMBOL_GPL (schedule_hrtimeout_range_clock);/** * schedule_hrtimeout_range - sleep until timeout
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 387/779 wireguard: allowedips: dont corrupt stack when detecting overflow
In reply to Greg Kroah-HartmanFrom: Jason A. Donenfeld <[email protected]>
[ Upstream commit c31b14d86dfe7174361e8c6e5df6c2c3a4d5918c ]
In case push_rcu() and related functions are buggy, there's a WARN_ON(len >= 128), which the selftest tries to hit by being tricky. In case it is hit, we shouldn't corrupt the kernel's stack, though; otherwise it may be hard to even receive the report that it's buggy. So conditionalize the stack write based on that WARN_ON()'s return value.
Note that this never *actually* happens anyway. The WARN_ON() in the first place is bounded by IS_ENABLED(DEBUG), and isn't expected to ever actually hit. This is just a debugging sanity check.
Additionally, hoist the constant 128 into a named enum, MAX_ALLOWEDIPS_BITS, so that it's clear why this value is chosen.
--- drivers/net/wireguard/allowedips.c | 9 ++++++--- drivers/net/wireguard/selftest/allowedips.c | 6 +++--- 2 files changed, 9 insertions(+), 6 deletions(-)
drivers/net/wireguard/allowedips.c +6 -3
@@ -6,6 +6,8 @@#include "allowedips.h" #include "peer.h" +enum {MAX_ALLOWEDIPS_BITS =128 }; +static struct kmem_cache *node_cache;static void swap_endian (u8 *dst,const u8 *src,u8 bits)
@@ -40,7 +42,8 @@ static void push_rcu(struct allowedips_node **stack, struct allowedips_node __rcu *p, unsigned int *len) { if (rcu_access_pointer(p)) { - WARN_ON(IS_ENABLED(DEBUG) && *len >= 128); + if (WARN_ON(IS_ENABLED(DEBUG) && *len >= MAX_ALLOWEDIPS_BITS)) + return; stack[(*len)++] =rcu_dereference_raw (p); } }
@@ -52,7 +55,7 @@ static void node_free_rcu(struct rcu_head *rcu)static void root_free_rcu (struct rcu_head *rcu) { -struct allowedips_node *node, *stack[128 ] = { +struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_BITS ] = { container_of(rcu, struct allowedips_node, rcu) };unsigned int len =1 ;
@@ -65,7 +68,7 @@ static void root_free_rcu(struct rcu_head *rcu)static void root_remove_peer_lists (struct allowedips_node *root) { -struct allowedips_node *node, *stack[128 ] = { root }; +struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_BITS ] = { root };unsigned int len =1 ;while (len >0 && (node = stack[--len])) {
drivers/net/wireguard/selftest/allowedips.c +3 -3
@@ -593,10 +593,10 @@ bool __init wg_allowedips_selftest(void)wg_allowedips_remove_by_peer (&t, a, &mutex);test_negative (4 , a,192 ,168 ,0 ,1 ); -/* These will hit the WARN_ON(len >= 128) in free_node if something -* goes wrong. +/* These will hit the WARN_ON(len >= MAX_ALLOWEDIPS_BITS) in free_node +* if something goes wrong. */ -for (i =0 ; i <128 ; ++i) { +for (i =0 ; i <MAX_ALLOWEDIPS_BITS ; ++i) { part =cpu_to_be64 (~(1LLU << (i %64 )));memset (&ip,0xff ,16 );memcpy ((u8 *)&ip + (i <64 ) *8 , &part,8 );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 388/779 HID: amd_sfh: Dont show client init failed as error when discovery fails
In reply to Greg Kroah-HartmanFrom: Mario Limonciello <[email protected]>
[ Upstream commit e51d8d3ea3d773334d2c047c8d1623dba66f592a ]
When sensor discovery fails, this means that the system doesn't have any sensors connected and a user should only be notified at most one time. A message is already displayed at WARN level of "failed to discover, sensors not enabled". It's pointless to show that the client init failed at ERR level for the same condition.
Check the return code and don't display this message in those conditions.
--- drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/hid/amd-sfh-hid/amd_sfh_pcie.c +2 -1
@@ -323,7 +323,8 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i rc =amd_sfh_hid_client_init (privdata);if (rc) {amd_sfh_clear_intr (privdata); -dev_err (&pdev->dev,"amd_sfh_hid_client_init failed\n" ); +if (rc != -EOPNOTSUPP ) +dev_err (&pdev->dev,"amd_sfh_hid_client_init failed\n" );return rc; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 389/779 clk: renesas: r9a06g032: Fix UART clkgrp bitsel
In reply to Greg Kroah-HartmanFrom: Ralph Siemsen <[email protected]>
[ Upstream commit 2dee50ab9e72a3cae75b65e5934c8dd3e9bf01bc ]
There are two UART clock groups, each having a mux to select its upstream clock source. The register/bit definitions for accessing these two muxes appear to have been reversed since introduction. Correct them so as to match the hardware manual.
--- drivers/clk/renesas/r9a06g032-clocks.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/clk/renesas/r9a06g032-clocks.c +4 -4
@@ -286,8 +286,8 @@ static const struct r9a06g032_clkdesc r9a06g032_clocks[] = { .name = "uart_group_012", .type = K_BITSEL, .source = 1 + R9A06G032_DIV_UART, - /* R9A06G032_SYSCTRL_REG_PWRCTRL_PG1_PR2 */ - .dual.sel = ((0xec / 4) << 5) | 24, + /* R9A06G032_SYSCTRL_REG_PWRCTRL_PG0_0 */ + .dual.sel = ((0x34 / 4) << 5) | 30, .dual.group = 0, }, {
@@ -295,8 +295,8 @@ static const struct r9a06g032_clkdesc r9a06g032_clocks[] = { .name = "uart_group_34567", .type = K_BITSEL, .source = 1 + R9A06G032_DIV_P2_PG, -/* R9A06G032_SYSCTRL_REG_PWRCTRL_PG0_0 */ - .dual.sel = ((0x34 / 4) << 5) | 30, +/* R9A06G032_SYSCTRL_REG_PWRCTRL_PG1_PR2 */ + .dual.sel = ((0xec / 4) << 5) | 24, .dual.group =1 , }, D_UGATE(CLK_UART0, "clk_uart0", UART_GROUP_012, 0, 0, 0x1b2, 0x1b3, 0x1b4, 0x1b5),
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 390/779 mtd: maps: Fix refcount leak in of_flash_probe_versatile
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit 33ec82a6d2b119938f26e5c8040ed5d92378eb54 ]
of_find_matching_node_and_match() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak.
--- drivers/mtd/maps/physmap-versatile.c | 1 + 1 file changed, 1 insertion(+)
drivers/mtd/maps/physmap-versatile.c +1 -0
@@ -207,6 +207,7 @@ int of_flash_probe_versatile(struct platform_device *pdev, versatile_flashprot = (enum versatile_flashprot )devid->data; rmap =syscon_node_to_regmap (sysnp); +of_node_put (sysnp);if (IS_ERR (rmap))return PTR_ERR (rmap);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 391/779 mtd: maps: Fix refcount leak in ap_flash_init
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit 77087a04c8fd554134bddcb8a9ff87b21f357926 ]
of_find_matching_node() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak.
--- drivers/mtd/maps/physmap-versatile.c | 1 + 1 file changed, 1 insertion(+)
drivers/mtd/maps/physmap-versatile.c +1 -0
@@ -93,6 +93,7 @@ static int ap_flash_init(struct platform_device *pdev)return -ENODEV ; } ebi_base =of_iomap (ebi,0 ); +of_node_put (ebi);if (!ebi_base)return -ENODEV ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 392/779 mtd: rawnand: meson: Fix a potential double free issue
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit ec0da06337751b18f6dee06b6526e0f0d6e80369 ]
When meson_nfc_nand_chip_cleanup() is called, it will call:
meson_nfc_free_buffer(&meson_chip->nand); nand_cleanup(&meson_chip->nand);
nand_cleanup() in turn will call nand_detach() which calls the .detach_chip() which is here meson_nand_detach_chip().
meson_nand_detach_chip() already calls meson_nfc_free_buffer(), so we could double free some memory.
Fix it by removing the unneeded explicit call to meson_nfc_free_buffer().
--- drivers/mtd/nand/raw/meson_nand.c | 1 - 1 file changed, 1 deletion(-)
drivers/mtd/nand/raw/meson_nand.c +0 -1
@@ -1307,7 +1307,6 @@ static int meson_nfc_nand_chip_cleanup(struct meson_nfc *nfc)if (ret)return ret; -meson_nfc_free_buffer (&meson_chip->nand);nand_cleanup (&meson_chip->nand);list_del (&meson_chip->node); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 393/779 of: check previous kernels ima-kexec-buffer against memory bounds
In reply to Greg Kroah-HartmanFrom: Vaibhav Jain <[email protected]>
[ Upstream commit cbf9c4b9617b6767886a913705ca14b7600c77db ]
Presently ima_get_kexec_buffer() doesn't check if the previous kernel's ima-kexec-buffer lies outside the addressable memory range. This can result in a kernel panic if the new kernel is booted with 'mem=X' arg and the ima-kexec-buffer was allocated beyond that range by the previous kernel. The panic is usually of the form below:
$ sudo kexec --initrd initrd vmlinux --append='mem=16G'
<snip>
BUG: Unable to handle kernel data access on read at 0xc000c01fff7f0000 Faulting instruction address: 0xc000000000837974 Oops: Kernel access of bad area, sig: 11 [#1] <snip> NIP [c000000000837974] ima_restore_measurement_list+0x94/0x6c0 LR [c00000000083b55c] ima_load_kexec_buffer+0xac/0x160 Call Trace: [c00000000371fa80] [c00000000083b55c] ima_load_kexec_buffer+0xac/0x160 [c00000000371fb00] [c0000000020512c4] ima_init+0x80/0x108 [c00000000371fb70] [c0000000020514dc] init_ima+0x4c/0x120 [c00000000371fbf0] [c000000000012240] do_one_initcall+0x60/0x2c0 [c00000000371fcc0] [c000000002004ad0] kernel_init_freeable+0x344/0x3ec [c00000000371fda0] [c0000000000128a4] kernel_init+0x34/0x1b0 [c00000000371fe10] [c00000000000ce64] ret_from_kernel_thread+0x5c/0x64 Instruction dump: f92100b8 f92100c0 90e10090 910100a0 4182050c 282a0017 3bc00000 40810330 7c0802a6 fb610198 7c9b2378 f80101d0 <a1240000> 2c090001 40820614 e9240010 ---[ end trace 0000000000000000 ]---
Fix this issue by checking returned PFN range of previous kernel's ima-kexec-buffer with page_is_ram() to ensure correct memory bounds.
--- drivers/of/kexec.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
drivers/of/kexec.c +17 -0
@@ -125,6 +125,7 @@ int ima_get_kexec_buffer(void **addr, size_t *size) {int ret, len;unsigned long tmp_addr; +unsigned long start_pfn, end_pfn;size_t tmp_size;const void *prop;
@@ -139,6 +140,22 @@ int ima_get_kexec_buffer(void **addr, size_t *size)if (ret)return ret; +/* Do some sanity on the returned size for the ima-kexec buffer */ +if (!tmp_size) +return -ENOENT ; + +/* +* Calculate the PFNs for the buffer and ensure +* they are with in addressable memory. +*/ + start_pfn =PHYS_PFN (tmp_addr); + end_pfn =PHYS_PFN (tmp_addr + tmp_size -1 ); +if (!page_is_ram (start_pfn) || !page_is_ram (end_pfn)) { +pr_warn ("IMA buffer at 0x%lx, size = 0x%zx beyond memory\n" , + tmp_addr, tmp_size); +return -EINVAL ; + } + *addr =__va (tmp_addr); *size = tmp_size;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 394/779 scsi: qla2xxx: edif: Reduce Initiator-Initiator thrashing
In reply to Greg Kroah-HartmanFrom: Quinn Tran <[email protected]>
[ Upstream commit 9c40c36e75ffd49952cd4ead0672defc4b4dbdf7 ]
This patch uses GFFID switch command to scan whether remote device is Target or Initiator mode. Based on that info, driver will not pass up Initiator info to authentication application. This helps reduce unnecessary stress for authentication application to deal with unused connections.
--- drivers/scsi/qla2xxx/qla_def.h | 2 + drivers/scsi/qla2xxx/qla_edif.c | 32 ++++++++- drivers/scsi/qla2xxx/qla_gbl.h | 3 +- drivers/scsi/qla2xxx/qla_gs.c | 118 +++++++++++++++++++++++--------- drivers/scsi/qla2xxx/qla_iocb.c | 2 +- 5 files changed, 120 insertions(+), 37 deletions(-)
drivers/scsi/qla2xxx/qla_def.h +2 -0
@@ -3201,6 +3201,8 @@ struct ct_sns_rsp {#define GFF_NVME_OFFSET 23/* type = 28h */ struct {uint8_t fc4_features[128 ]; +#define FC4_FF_TARGET BIT_0 +#define FC4_FF_INITIATOR BIT_1 } gff_id;struct {uint8_t reserved;
drivers/scsi/qla2xxx/qla_edif.c +29 -3
@@ -517,16 +517,28 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)if (atomic_read (&vha->loop_state) ==LOOP_DOWN )break ; - fcport->edif.app_started =1 ; fcport->login_retry = vha->hw->login_retry_count; -/* no activity */ fcport->edif.app_stop =0 ; + fcport->edif.app_sess_online =0 ; + fcport->edif.app_started =1 ; + +if (fcport->scan_state !=QLA_FCPORT_FOUND ) +continue ; + +if (fcport->port_type ==FCT_UNKNOWN && + !fcport->fc4_features) + rval =qla24xx_async_gffid (vha, fcport, true); + +if (!rval && !(fcport->fc4_features &FC4_FF_TARGET || + fcport->port_type & (FCT_TARGET |FCT_NVME_TARGET ))) +continue ; + + rval =0 ;ql_dbg (ql_dbg_edif, vha,0x911e ,"%s wwpn %8phC calling qla_edif_reset_auth_wait\n" , __func__, fcport->port_name); - fcport->edif.app_sess_online =0 ;qlt_schedule_sess_for_deletion (fcport);qla_edif_sa_ctl_init (vha, fcport); }
@@ -884,6 +896,20 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job) app_reply->ports[pcnt].rekey_count = fcport->edif.rekey_cnt; +if (fcport->scan_state !=QLA_FCPORT_FOUND ) +continue ; + +if (fcport->port_type ==FCT_UNKNOWN && !fcport->fc4_features) + rval =qla24xx_async_gffid (vha, fcport, true); + +if (!rval && + !(fcport->fc4_features &FC4_FF_TARGET || + fcport->port_type & + (FCT_TARGET |FCT_NVME_TARGET ))) +continue ; + + rval =0 ; + app_reply->ports[pcnt].remote_type =VND_CMD_RTYPE_UNKNOWN ;if (fcport->port_type & (FCT_NVME_TARGET |FCT_TARGET ))
drivers/scsi/qla2xxx/qla_gbl.h +2 -1
@@ -334,6 +334,7 @@ extern int qla24xx_configure_prot_mode(srb_t *, uint16_t *);extern int qla24xx_issue_sa_replace_iocb (scsi_qla_host_t *vha,struct qla_work_evt *e);void qla2x00_sp_release (struct kref *kref); +void qla2x00_els_dcmd2_iocb_timeout (void *data);/* * Global Function Prototypes in qla_mbx.c source file.
@@ -722,7 +723,7 @@ int qla24xx_async_gpsc(scsi_qla_host_t *, fc_port_t *);void qla24xx_handle_gpsc_event (scsi_qla_host_t *,struct event_arg *);int qla2x00_mgmt_svr_login (scsi_qla_host_t *);void qla24xx_handle_gffid_event (scsi_qla_host_t *vha,struct event_arg *ea); -int qla24xx_async_gffid (scsi_qla_host_t *vha,fc_port_t *fcport); +int qla24xx_async_gffid (scsi_qla_host_t *vha,fc_port_t *fcport,bool );int qla24xx_async_gpnft (scsi_qla_host_t *,u8 ,srb_t *);void qla24xx_async_gpnft_done (scsi_qla_host_t *,srb_t *);void qla24xx_async_gnnft_done (scsi_qla_host_t *,srb_t *);
drivers/scsi/qla2xxx/qla_gs.c +86 -32
182 lines not on this page · raw message
drivers/scsi/qla2xxx/qla_iocb.c +1 -1
@@ -2819,7 +2819,7 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb) sp->vha->qla_stats.control_requests++; } -static void +void qla2x00_els_dcmd2_iocb_timeout (void *data) {srb_t *sp = data;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 395/779 scsi: qla2xxx: edif: Fix potential stuck session in sa update
In reply to Greg Kroah-HartmanFrom: Quinn Tran <[email protected]>
[ Upstream commit e0fb8ce2bb9e52c846e54ad2c58b5b7beb13eb09 ]
When a thread is in the process of reestablish a session, a flag is set to prevent multiple threads/triggers from doing the same task. This flag was left on, and any attempt to relogin was locked out. Clear this flag if the attempt has failed.
--- drivers/scsi/qla2xxx/qla_edif.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
drivers/scsi/qla2xxx/qla_edif.c +14 -3
@@ -2187,6 +2187,7 @@ edif_doorbell_show(struct device *dev, struct device_attribute *attr,static void qla_noop_sp_done (srb_t *sp,int res) { + sp->fcport->flags &= ~(FCF_ASYNC_SENT |FCF_ASYNC_ACTIVE );/* ref: INIT */ kref_put (&sp->cmd_kref, qla2x00_sp_release); }
@@ -2211,7 +2212,8 @@ qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, struct qla_work_evt *e)if (!sa_ctl) {ql_dbg (ql_dbg_edif, vha,0x70e6 ,"sa_ctl allocation failed\n" ); -return -ENOMEM ; + rval = -ENOMEM ; + goto done; } fcport = sa_ctl->fcport;
@@ -2221,7 +2223,8 @@ qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, struct qla_work_evt *e)if (!sp) {ql_dbg (ql_dbg_edif, vha,0x70e6 ,"SRB allocation failed\n" ); -return -ENOMEM ; + rval = -ENOMEM ; + goto done; } fcport->flags |=FCF_ASYNC_SENT ;
@@ -2250,9 +2253,17 @@ qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, struct qla_work_evt *e) rval =qla2x00_start_sp (sp); -if (rval !=QLA_SUCCESS ) +if (rval !=QLA_SUCCESS ) { rval =QLA_FUNCTION_FAILED ; + goto done_free_sp; + } +return rval; +done_free_sp: +kref_put (&sp->cmd_kref, qla2x00_sp_release); + fcport->flags &= ~FCF_ASYNC_SENT ; +done: + fcport->flags &= ~FCF_ASYNC_ACTIVE ;return rval; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 396/779 scsi: qla2xxx: edif: Reduce connection thrash
In reply to Greg Kroah-HartmanFrom: Quinn Tran <[email protected]>
[ Upstream commit 91f6f5fbe87ba834133fcc61d34881cb8ec9e518 ]
On ipsec start by remote port, target port may use RSCN to trigger initiator to relogin. If driver is already in the process of a relogin, then ignore the RSCN and allow the current relogin to continue. This reduces thrashing of the connection.
--- drivers/scsi/qla2xxx/qla_attr.c | 7 ++++++- drivers/scsi/qla2xxx/qla_edif.h | 4 ++++ drivers/scsi/qla2xxx/qla_init.c | 24 ++++++++++++++++++++++-- 3 files changed, 32 insertions(+), 3 deletions(-)
drivers/scsi/qla2xxx/qla_attr.c +6 -1
@@ -2754,7 +2754,12 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)if (fcport->loop_id !=FC_NO_LOOP_ID ) fcport->logout_on_delete =1 ; -qlt_schedule_sess_for_deletion (fcport); +if (!EDIF_NEGOTIATION_PENDING (fcport)) { +ql_dbg (ql_dbg_disc, fcport->vha,0x911e , +"%s %d schedule session deletion\n" , __func__, + __LINE__); +qlt_schedule_sess_for_deletion (fcport); + } }else {qla2x00_port_logout (fcport->vha, fcport); }
drivers/scsi/qla2xxx/qla_edif.h +4 -0
@@ -133,4 +133,8 @@ struct enode { _s->disc_state == DSC_DELETED || \ !_s->edif.app_sess_online)) +#define EDIF_NEGOTIATION_PENDING (_fcport) \ + ((_fcport->vha.e_dbell.db_flags & EDB_ACTIVE) && \ + (_fcport->disc_state == DSC_LOGIN_AUTH_PEND)) +#endif /* __QLA_EDIF_H */
drivers/scsi/qla2xxx/qla_init.c +22 -2
@@ -1825,8 +1825,28 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea) fcport->d_id.b24, fcport->port_name);return ; } - fcport->scan_needed =1 ; - fcport->rscn_gen++; + +if (vha->hw->flags.edif_enabled && vha->e_dbell.db_flags &EDB_ACTIVE ) { +/* +* On ipsec start by remote port, Target port +* may use RSCN to trigger initiator to +* relogin. If driver is already in the +* process of a relogin, then ignore the RSCN +* and allow the current relogin to continue. +* This reduces thrashing of the connection. +*/ +if (atomic_read (&fcport->state) ==FCS_ONLINE ) { +/* +* If state = online, then set scan_needed=1 to do relogin. +* Otherwise we're already in the middle of a relogin +*/ + fcport->scan_needed =1 ; + fcport->rscn_gen++; + } + }else { + fcport->scan_needed =1 ; + fcport->rscn_gen++; + } }break ;case RSCN_AREA_ADDR :
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 397/779 scsi: qla2xxx: edif: Fix inconsistent check of db_flags
In reply to Greg Kroah-HartmanFrom: Quinn Tran <[email protected]>
[ Upstream commit 36f468bfe98c7de7916ab3391ee5dd6fd2549979 ]
db_flags field is a bit field. Replace value check with bit flag check.
--- drivers/scsi/qla2xxx/qla_edif.c | 26 +++++++++++++------------- drivers/scsi/qla2xxx/qla_edif.h | 7 +++++-- drivers/scsi/qla2xxx/qla_init.c | 13 ++++++------- drivers/scsi/qla2xxx/qla_iocb.c | 3 +-- drivers/scsi/qla2xxx/qla_target.c | 2 +- 5 files changed, 26 insertions(+), 25 deletions(-)
drivers/scsi/qla2xxx/qla_edif.c +13 -13
@@ -218,7 +218,7 @@ fc_port_t *fcport) "%s edif not enabled\n", __func__); goto done; } -if (vha->e_dbell.db_flags !=EDB_ACTIVE ) { +if (DBELL_INACTIVE (vha)) {ql_dbg (ql_dbg_edif, vha,0x09102 ,"%s doorbell not enabled\n" , __func__); goto done;
@@ -482,9 +482,9 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)ql_dbg (ql_dbg_edif, vha,0x911d ,"%s app_vid=%x app_start_flags %x\n" , __func__, appstart.app_info.app_vid, appstart.app_start_flags); -if (vha->e_dbell.db_flags !=EDB_ACTIVE ) { +if (DBELL_INACTIVE (vha)) {/* mark doorbell as active since an app is now present */ - vha->e_dbell.db_flags =EDB_ACTIVE ; + vha->e_dbell.db_flags |=EDB_ACTIVE ; }else {ql_dbg (ql_dbg_edif, vha,0x911e ,"%s doorbell already active\n" , __func__);
@@ -1306,7 +1306,7 @@ qla24xx_sadb_update(struct bsg_job *bsg_job) goto done; } -if (vha->e_dbell.db_flags !=EDB_ACTIVE ) { +if (DBELL_INACTIVE (vha)) {ql_log (ql_log_warn, vha,0x70a1 ,"App not started\n" ); rval = -EIO ;SET_DID_STATUS (bsg_reply->result,DID_ERROR );
@@ -1813,7 +1813,7 @@ qla_els_reject_iocb(scsi_qla_host_t *vha, struct qla_qpair *qp,void qla_edb_init (scsi_qla_host_t *vha) { -if (vha->e_dbell.db_flags ==EDB_ACTIVE ) { +if (DBELL_ACTIVE (vha)) {/* list already init'd - error */ ql_dbg (ql_dbg_edif, vha,0x09102 ,"edif db already initialized, cannot reinit\n" );
@@ -1856,7 +1856,7 @@ static void qla_edb_clear(scsi_qla_host_t *vha, port_id_t portid)port_id_t sid;LIST_HEAD (edb_list); -if (vha->e_dbell.db_flags !=EDB_ACTIVE ) { +if (DBELL_INACTIVE (vha)) {/* doorbell list not enabled */ ql_dbg (ql_dbg_edif, vha,0x09102 ,"%s doorbell not enabled\n" , __func__);
@@ -1908,7 +1908,7 @@ qla_edb_stop(scsi_qla_host_t *vha)unsigned long flags;struct edb_node *node, *q; -if (vha->e_dbell.db_flags !=EDB_ACTIVE ) { +if (DBELL_INACTIVE (vha)) {/* doorbell list not enabled */ ql_dbg (ql_dbg_edif, vha,0x09102 ,"%s doorbell not enabled\n" , __func__);
@@ -1959,7 +1959,7 @@ qla_edb_node_add(scsi_qla_host_t *vha, struct edb_node *ptr) {unsigned long flags; -if (vha->e_dbell.db_flags !=EDB_ACTIVE ) { +if (DBELL_INACTIVE (vha)) {/* doorbell list not enabled */ ql_dbg (ql_dbg_edif, vha,0x09102 ,"%s doorbell not enabled\n" , __func__);
@@ -1990,7 +1990,7 @@ qla_edb_eventcreate(scsi_qla_host_t *vha, uint32_t dbtype,return ; } -if (vha->e_dbell.db_flags !=EDB_ACTIVE ) { +if (DBELL_INACTIVE (vha)) {if (fcport) fcport->edif.auth_state = dbtype;/* doorbell list not enabled */
@@ -2085,7 +2085,7 @@ qla_edif_timer(scsi_qla_host_t *vha)struct qla_hw_data *ha = vha->hw;if (!vha->vp_idx &&N2N_TOPO (ha) && ha->flags.n2n_fw_acc_sec) { -if (vha->e_dbell.db_flags !=EDB_ACTIVE && +if (DBELL_INACTIVE (vha) && ha->edif_post_stop_cnt_down) { ha->edif_post_stop_cnt_down--;
@@ -2123,7 +2123,7 @@ edif_doorbell_show(struct device *dev, struct device_attribute *attr, sz =256 ;/* stop new threads from waiting if we're not init'd */ -if (vha->e_dbell.db_flags !=EDB_ACTIVE ) { +if (DBELL_INACTIVE (vha)) {ql_dbg (ql_dbg_edif + ql_dbg_verbose, vha,0x09122 ,"%s error - edif db not enabled\n" , __func__);return 0 ;
@@ -2480,7 +2480,7 @@ void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp) fcport =qla2x00_find_fcport_by_pid (host, &purex->pur_info.pur_sid); -if (host->e_dbell.db_flags !=EDB_ACTIVE || +if (DBELL_INACTIVE (vha) || (fcport &&EDIF_SESSION_DOWN (fcport))) { ql_dbg(ql_dbg_edif, host, 0x0910c, "%s e_dbell.db_flags =%x %06x\n", __func__, host->e_dbell.db_flags,
@@ -3506,7 +3506,7 @@ int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job)void qla_edif_sess_down (struct scsi_qla_host *vha,struct fc_port *sess) { -if (sess->edif.app_sess_online && vha->e_dbell.db_flags &EDB_ACTIVE ) { +if (sess->edif.app_sess_online &&DBELL_ACTIVE (vha)) {ql_dbg (ql_dbg_disc, vha,0xf09c ,"%s: sess %8phN send port_offline event\n" , __func__, sess->port_name);
drivers/scsi/qla2xxx/qla_edif.h +5 -2
@@ -41,9 +41,12 @@ struct pur_core { };enum db_flags_t { -EDB_ACTIVE =0x1 , +EDB_ACTIVE =BIT_0 , }; +#define DBELL_ACTIVE (_v) (_v->e_dbell.db_flags & EDB_ACTIVE) +#define DBELL_INACTIVE (_v) (!(_v->e_dbell.db_flags & EDB_ACTIVE)) +struct edif_dbell {enum db_flags_t db_flags;spinlock_t db_lock;
@@ -134,7 +137,7 @@ struct enode { !_s->edif.app_sess_online))#define EDIF_NEGOTIATION_PENDING (_fcport) \ - ((_fcport->vha.e_dbell.db_flags & EDB_ACTIVE) && \ + (DBELL_ACTIVE(_fcport->vha) && \ (_fcport->disc_state == DSC_LOGIN_AUTH_PEND))#endif /* __QLA_EDIF_H */
drivers/scsi/qla2xxx/qla_init.c +6 -7
@@ -341,7 +341,7 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport, lio->u.logio.flags |=SRB_LOGIN_PRLI_ONLY ; }else {if (vha->hw->flags.edif_enabled && - vha->e_dbell.db_flags &EDB_ACTIVE ) { +DBELL_ACTIVE (vha)) { lio->u.logio.flags |= (SRB_LOGIN_FCSP |SRB_LOGIN_SKIP_PRLI ); ql_dbg(ql_dbg_disc, vha, 0x2072,
@@ -881,7 +881,7 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,break ;case DSC_LS_PLOGI_COMP :if (vha->hw->flags.edif_enabled && - vha->e_dbell.db_flags &EDB_ACTIVE ) { +DBELL_ACTIVE (vha)) {/* check to see if App support secure or not */ qla24xx_post_gpdb_work (vha, fcport,0 );break ;
@@ -1477,7 +1477,7 @@ static int qla_chk_secure_login(scsi_qla_host_t *vha, fc_port_t *fcport,qla2x00_post_aen_work (vha,FCH_EVT_PORT_ONLINE , fcport->d_id.b24); -if (vha->e_dbell.db_flags ==EDB_ACTIVE ) { +if (DBELL_ACTIVE (vha)) {ql_dbg (ql_dbg_disc, vha,0x20ef ,"%s %d %8phC EDIF: post DB_AUTH: AUTH needed\n" , __func__, __LINE__, fcport->port_name);
@@ -1826,7 +1826,7 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea)return ; } -if (vha->hw->flags.edif_enabled && vha->e_dbell.db_flags &EDB_ACTIVE ) { +if (vha->hw->flags.edif_enabled &&DBELL_ACTIVE (vha)) {/* * On ipsec start by remote port, Target port * may use RSCN to trigger initiator to
@@ -4266,7 +4266,7 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)* fw shal not send PRLI after PLOGI Acc */ if (ha->flags.edif_enabled && - vha->e_dbell.db_flags &EDB_ACTIVE ) { +DBELL_ACTIVE (vha)) { ha->fw_options[3 ] |=BIT_15 ; ha->flags.n2n_fw_acc_sec =1 ; }else {
@@ -5424,8 +5424,7 @@ qla2x00_configure_loop(scsi_qla_host_t *vha)* use link up to wake up app to get ready for * authentication. */ -if (ha->flags.edif_enabled && - !(vha->e_dbell.db_flags &EDB_ACTIVE )) +if (ha->flags.edif_enabled &&DBELL_INACTIVE (vha))qla2x00_post_aen_work (vha,FCH_EVT_LINKUP , ha->link_data_rate);
drivers/scsi/qla2xxx/qla_iocb.c +1 -2
@@ -3065,8 +3065,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode, elsio->u.els_plogi.els_cmd = els_opcode; elsio->u.els_plogi.els_plogi_pyld->opcode = els_opcode; -if (els_opcode ==ELS_DCMD_PLOGI && vha->hw->flags.edif_enabled && - vha->e_dbell.db_flags &EDB_ACTIVE ) { +if (els_opcode ==ELS_DCMD_PLOGI &&DBELL_ACTIVE (vha)) {struct fc_els_flogi *p = ptr; p->fl_csp.sp_features |=cpu_to_be16 (FC_SP_FT_SEC );
drivers/scsi/qla2xxx/qla_target.c +1 -1
@@ -4815,7 +4815,7 @@ static int qlt_handle_login(struct scsi_qla_host *vha, }if (vha->hw->flags.edif_enabled) { -if (!(vha->e_dbell.db_flags &EDB_ACTIVE )) { +if (DBELL_INACTIVE (vha)) {ql_dbg (ql_dbg_disc, vha,0xffff ,"%s %d Term INOT due to app not started lid=%d, NportID %06X " , __func__, __LINE__, loop_id, port_id.b24);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 398/779 scsi: qla2xxx: edif: Synchronize NPIV deletion with authentication application
In reply to Greg Kroah-HartmanFrom: Quinn Tran <[email protected]>
[ Upstream commit cf79716e6636400ae38c37bc8a652b1e522abbba ]
Notify authentication application of a NPIV deletion event is about to occur. This allows app to perform cleanup.
--- drivers/scsi/qla2xxx/qla_edif_bsg.h | 2 ++ drivers/scsi/qla2xxx/qla_mid.c | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-)
drivers/scsi/qla2xxx/qla_edif_bsg.h +2 -0
@@ -217,4 +217,6 @@ struct auth_complete_cmd {#define RX_DELAY_DELETE_TIMEOUT 20 +#define FCH_EVT_VENDOR_UNIQUE_VPORT_DOWN 1 +#endif /* QLA_EDIF_BSG_H */
drivers/scsi/qla2xxx/qla_mid.c +5 -1
@@ -166,9 +166,13 @@ qla24xx_disable_vp(scsi_qla_host_t *vha)int ret =QLA_SUCCESS ;fc_port_t *fcport; -if (vha->hw->flags.edif_enabled) +if (vha->hw->flags.edif_enabled) { +if (DBELL_ACTIVE (vha)) +qla2x00_post_aen_work (vha,FCH_EVT_VENDOR_UNIQUE , +FCH_EVT_VENDOR_UNIQUE_VPORT_DOWN );/* delete sessions and flush sa_indexes */ qla2x00_wait_for_sess_deletion (vha); + }if (vha->hw->flags.fw_started) ret =qla24xx_control_vp (vha,VCE_COMMAND_DISABLE_VPS_LOGO_ALL );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 399/779 scsi: qla2xxx: edif: Add retry for ELS passthrough
In reply to Greg Kroah-HartmanFrom: Quinn Tran <[email protected]>
[ Upstream commit 0b3f3143d473b489a7aa0779c43bcdb344bd3014 ]
Relating to EDIF, when sending IKE message, updating key or deleting key, driver can encounter IOCB queue full. Add additional retries to reduce higher level recovery.
--- drivers/scsi/qla2xxx/qla_edif.c | 52 +++++++++++++++++++++++---------- drivers/scsi/qla2xxx/qla_os.c | 2 +- 2 files changed, 38 insertions(+), 16 deletions(-)
drivers/scsi/qla2xxx/qla_edif.c +37 -15
@@ -1274,6 +1274,8 @@ qla24xx_check_sadb_avail_slot(struct bsg_job *bsg_job, fc_port_t *fcport,#define QLA_SA_UPDATE_FLAGS_RX_KEY 0x0#define QLA_SA_UPDATE_FLAGS_TX_KEY 0x2 +#define EDIF_MSLEEP_INTERVAL 100 +#define EDIF_RETRY_COUNT 50int qla24xx_sadb_update (struct bsg_job *bsg_job)
@@ -1286,7 +1288,7 @@ qla24xx_sadb_update(struct bsg_job *bsg_job)struct edif_list_entry *edif_entry =NULL ;int found =0 ;int rval =0 ; -int result =0 ; +int result =0 , cnt;struct qla_sa_update_frame sa_frame;struct srb_iocb *iocb_cmd;port_id_t portid;
@@ -1527,11 +1529,23 @@ qla24xx_sadb_update(struct bsg_job *bsg_job) sp->done = qla2x00_bsg_job_done; iocb_cmd = &sp->u.iocb_cmd; iocb_cmd->u.sa_update.sa_frame = sa_frame; - + cnt =0 ; +retry: rval =qla2x00_start_sp (sp); -if (rval !=QLA_SUCCESS ) { +switch (rval) { +case QLA_SUCCESS : +break ; +case EAGAIN : +msleep (EDIF_MSLEEP_INTERVAL ); + cnt++; +if (cnt <EDIF_RETRY_COUNT ) + goto retry; + + fallthrough; +default :ql_log (ql_dbg_edif, vha,0x70e3 , -"qla2x00_start_sp failed=%d.\n" , rval); +"%s qla2x00_start_sp failed=%d.\n" , + __func__, rval);qla2x00_rel_sp (sp); rval = -EIO ;
@@ -2254,7 +2268,6 @@ qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, struct qla_work_evt *e) rval =qla2x00_start_sp (sp);if (rval !=QLA_SUCCESS ) { - rval =QLA_FUNCTION_FAILED ; goto done_free_sp; }
@@ -3383,7 +3396,7 @@ int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job)fc_port_t *fcport =NULL ;struct qla_hw_data *ha = vha->hw;srb_t *sp; -int rval = (DID_ERROR <<16 ); +int rval = (DID_ERROR <<16 ), cnt;port_id_t d_id;struct qla_bsg_auth_els_request *p = (struct qla_bsg_auth_els_request *)bsg_job->request;
@@ -3474,17 +3487,26 @@ int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job) sp->free = qla2x00_bsg_sp_free; sp->done = qla2x00_bsg_job_done; + cnt =0 ; +retry: rval =qla2x00_start_sp (sp); - -ql_dbg (ql_dbg_edif, vha,0x700a , -"%s %s %8phN xchg %x ctlflag %x hdl %x reqlen %xh bsg ptr %p\n" , - __func__,sc_to_str (p->e.sub_cmd), fcport->port_name, - p->e.extra_rx_xchg_address, p->e.extra_control_flags, - sp->handle, sp->remap.req.len, bsg_job); - -if (rval !=QLA_SUCCESS ) { +switch (rval) { +case QLA_SUCCESS : +ql_dbg (ql_dbg_edif, vha,0x700a , +"%s %s %8phN xchg %x ctlflag %x hdl %x reqlen %xh bsg ptr %p\n" , + __func__,sc_to_str (p->e.sub_cmd), fcport->port_name, + p->e.extra_rx_xchg_address, p->e.extra_control_flags, + sp->handle, sp->remap.req.len, bsg_job); +break ; +case EAGAIN : +msleep (EDIF_MSLEEP_INTERVAL ); + cnt++; +if (cnt <EDIF_RETRY_COUNT ) + goto retry; + fallthrough; +default :ql_log (ql_log_warn, vha,0x700e , -"qla2x00_start_sp failed = %d\n" , rval); +"%s qla2x00_start_sp failed = %d\n" , __func__, rval);SET_DID_STATUS (bsg_reply->result,DID_IMM_RETRY ); rval = -EIO ; goto done_free_remap_rsp;
drivers/scsi/qla2xxx/qla_os.c +1 -1
@@ -5466,7 +5466,7 @@ qla2x00_do_work(struct scsi_qla_host *vha) e->u.fcport.fcport, false);break ;case QLA_EVT_SA_REPLACE : -qla24xx_issue_sa_replace_iocb (vha, e); + rc =qla24xx_issue_sa_replace_iocb (vha, e);break ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 400/779 scsi: qla2xxx: edif: Fix n2n discovery issue with secure target
In reply to Greg Kroah-HartmanFrom: Quinn Tran <[email protected]>
[ Upstream commit 789d54a4178634850e441f60c0326124138e7269 ]
User failed to see disk via n2n topology. Driver used up all login retries before authentication application started. When authentication application started, driver did not have enough login retries to connect securely. On app_start, driver will reset the login retry attempt count.
--- drivers/scsi/qla2xxx/qla_edif.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/scsi/qla2xxx/qla_edif.c +3 -0
@@ -491,6 +491,9 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job) }if (N2N_TOPO (vha->hw)) { +list_for_each_entry_safe (fcport, tf, &vha->vp_fcports, list) + fcport->n2n_link_reset_cnt =0 ; +if (vha->hw->flags.n2n_fw_acc_sec)set_bit (N2N_LINK_RESET , &vha->dpc_flags);else
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 401/779 scsi: qla2xxx: edif: Fix n2n login retry for secure device
In reply to Greg Kroah-HartmanFrom: Quinn Tran <[email protected]>
[ Upstream commit aec55325ddec975216119da000092cb8664a3399 ]
After initiator has burned up all login retries, target authentication application begins to run. This triggers a link bounce on target side. Initiator will attempt another login. Due to N2N, the PRLI [nvme | fcp] can fail because of the mode mismatch with target. This patch add a few more login retries to revive the connection.
--- drivers/scsi/qla2xxx/qla_init.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/scsi/qla2xxx/qla_init.c +7 -0
@@ -2125,6 +2125,13 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea) }if (N2N_TOPO (vha->hw)) { +if (ea->fcport->n2n_link_reset_cnt == + vha->hw->login_retry_count && + ea->fcport->flags &FCF_FCSP_DEVICE ) { +/* remote authentication app just started */ + ea->fcport->n2n_link_reset_cnt =0 ; + } +if (ea->fcport->n2n_link_reset_cnt < vha->hw->login_retry_count) { ea->fcport->n2n_link_reset_cnt++;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 402/779 KVM: SVM: Unwind "speculative" RIP advancement if INTn injection "fails"
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
[ Upstream commit cd9e6da8048c5b40315ee2d929b6230ce1252c3c ]
Unwind the RIP advancement done by svm_queue_exception() when injecting an INT3 ultimately "fails" due to the CPU encountering a VM-Exit while vectoring the injected event, even if the exception reported by the CPU isn't the same event that was injected. If vectoring INT3 encounters an exception, e.g. #NP, and vectoring the #NP encounters an intercepted exception, e.g. #PF when KVM is using shadow paging, then the #NP will be reported as the event that was in-progress.
Note, this is still imperfect, as it will get a false positive if the INT3 is cleanly injected, no VM-Exit occurs before the IRET from the INT3 handler in the guest, the instruction following the INT3 generates an exception (directly or indirectly), _and_ vectoring that exception encounters an exception that is intercepted by KVM. The false positives could theoretically be solved by further analyzing the vectoring event, e.g. by comparing the error code against the expected error code were an exception to occur when vectoring the original injected exception, but SVM without NRIPS is a complete disaster, trying to make it 100% correct is a waste of time.
Message-Id: <450133cf0a026cb9825a2ff55d02cb136a1cb111.1651440202.git.maciej.szmigiero@oracle.com>
--- arch/x86/kvm/svm/svm.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-)
arch/x86/kvm/svm/svm.c +15 -8
@@ -3680,6 +3680,18 @@ static void svm_complete_interrupts(struct kvm_vcpu *vcpu) vector = exitintinfo &SVM_EXITINTINFO_VEC_MASK ; type = exitintinfo &SVM_EXITINTINFO_TYPE_MASK ; +/* +* If NextRIP isn't enabled, KVM must manually advance RIP prior to +* injecting the soft exception/interrupt. That advancement needs to +* be unwound if vectoring didn't complete. Note, the _new_ event may +* not be the injected event, e.g. if KVM injected an INTn, the INTn +* hit a #NP in the guest, and the #NP encountered a #PF, the #NP will +* be the reported vectored event, but RIP still needs to be unwound. +*/ +if (int3_injected && type ==SVM_EXITINTINFO_TYPE_EXEPT && +kvm_is_linear_rip (vcpu, svm->int3_rip)) +kvm_rip_write (vcpu,kvm_rip_read (vcpu) - int3_injected); +switch (type) {case SVM_EXITINTINFO_TYPE_NMI : vcpu->arch.nmi_injected = true;
@@ -3693,16 +3705,11 @@ static void svm_complete_interrupts(struct kvm_vcpu *vcpu)/* * In case of software exceptions, do not reinject the vector, -* but re-execute the instruction instead. Rewind RIP first -* if we emulated INT3 before. +* but re-execute the instruction instead. */ -if (kvm_exception_is_soft (vector)) { -if (vector ==BP_VECTOR && int3_injected && -kvm_is_linear_rip (vcpu, svm->int3_rip)) -kvm_rip_write (vcpu, -kvm_rip_read (vcpu) - int3_injected); +if (kvm_exception_is_soft (vector))break ; - } +if (exitintinfo &SVM_EXITINTINFO_VALID_ERR ) {u32 err = svm->vmcb->control.exit_int_info_err;kvm_requeue_exception_e (vcpu, vector, err);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 403/779 KVM: SVM: Stuff next_rip on emulated INT3 injection if NRIPS is supported
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
[ Upstream commit 3741aec4c38fa4123ab08ae552f05366d4fd05d8 ]
If NRIPS is supported in hardware but disabled in KVM, set next_rip to the next RIP when advancing RIP as part of emulating INT3 injection. There is no flag to tell the CPU that KVM isn't using next_rip, and so leaving next_rip is left as is will result in the CPU pushing garbage onto the stack when vectoring the injected event.
Message-Id: <cd328309a3b88604daa2359ad56f36cb565ce2d4.1651440202.git.maciej.szmigiero@oracle.com>
--- arch/x86/kvm/svm/svm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
arch/x86/kvm/svm/svm.c +5 -1
@@ -394,6 +394,10 @@ static void svm_queue_exception(struct kvm_vcpu *vcpu)*/ (void )skip_emulated_instruction (vcpu); rip =kvm_rip_read (vcpu); + +if (boot_cpu_has (X86_FEATURE_NRIPS )) + svm->vmcb->control.next_rip = rip; + svm->int3_rip = rip + svm->vmcb->save.cs.base; svm->int3_injected = rip - old_rip; }
@@ -3683,7 +3687,7 @@ static void svm_complete_interrupts(struct kvm_vcpu *vcpu)/* * If NextRIP isn't enabled, KVM must manually advance RIP prior to * injecting the soft exception/interrupt. That advancement needs to -* be unwound if vectoring didn't complete. Note, the _new_ event may +* be unwound if vectoring didn't complete. Note, the new event may * not be the injected event, e.g. if KVM injected an INTn, the INTn * hit a #NP in the guest, and the #NP encountered a #PF, the #NP will * be the reported vectored event, but RIP still needs to be unwound.
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 404/779 phy: samsung: exynosautov9-ufs: correct TSRV register configurations
In reply to Greg Kroah-HartmanFrom: Chanho Park <[email protected]>
[ Upstream commit f7fdc4db071f7ee7d408ea3f083222a060c76623 ]
For exynos auto v9's UFS MPHY, We should use 0x50 offset of TSRV register configurations. So, it must be
s/PHY_TRSV_REG_CFG/PHY_TRSV_REG_CFG_AUTOV9/g
--- drivers/phy/samsung/phy-exynosautov9-ufs.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
drivers/phy/samsung/phy-exynosautov9-ufs.c +9 -9
@@ -31,22 +31,22 @@ static const struct samsung_ufs_phy_cfg exynosautov9_pre_init_cfg[] = {PHY_COMN_REG_CFG (0x023 ,0xc0 ,PWR_MODE_ANY ),PHY_COMN_REG_CFG (0x023 ,0x00 ,PWR_MODE_ANY ), -PHY_TRSV_REG_CFG (0x042 ,0x5d ,PWR_MODE_ANY ), -PHY_TRSV_REG_CFG (0x043 ,0x80 ,PWR_MODE_ANY ), +PHY_TRSV_REG_CFG_AUTOV9 (0x042 ,0x5d ,PWR_MODE_ANY ), +PHY_TRSV_REG_CFG_AUTOV9 (0x043 ,0x80 ,PWR_MODE_ANY ), END_UFS_PHY_CFG, };/* Calibration for HS mode series A/B */ static const struct samsung_ufs_phy_cfg exynosautov9_pre_pwr_hs_cfg[] = { -PHY_TRSV_REG_CFG (0x032 ,0xbc ,PWR_MODE_HS_ANY ), -PHY_TRSV_REG_CFG (0x03c ,0x7f ,PWR_MODE_HS_ANY ), -PHY_TRSV_REG_CFG (0x048 ,0xc0 ,PWR_MODE_HS_ANY ), +PHY_TRSV_REG_CFG_AUTOV9 (0x032 ,0xbc ,PWR_MODE_HS_ANY ), +PHY_TRSV_REG_CFG_AUTOV9 (0x03c ,0x7f ,PWR_MODE_HS_ANY ), +PHY_TRSV_REG_CFG_AUTOV9 (0x048 ,0xc0 ,PWR_MODE_HS_ANY ), -PHY_TRSV_REG_CFG (0x04a ,0x00 ,PWR_MODE_HS_G3_SER_B ), -PHY_TRSV_REG_CFG (0x04b ,0x10 ,PWR_MODE_HS_G1_SER_B | -PWR_MODE_HS_G3_SER_B ), -PHY_TRSV_REG_CFG (0x04d ,0x63 ,PWR_MODE_HS_G3_SER_B ), +PHY_TRSV_REG_CFG_AUTOV9 (0x04a ,0x00 ,PWR_MODE_HS_G3_SER_B ), +PHY_TRSV_REG_CFG_AUTOV9 (0x04b ,0x10 ,PWR_MODE_HS_G1_SER_B | +PWR_MODE_HS_G3_SER_B ), +PHY_TRSV_REG_CFG_AUTOV9 (0x04d ,0x63 ,PWR_MODE_HS_G3_SER_B ),END_UFS_PHY_CFG , };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 405/779 PCI: microchip: Fix refcount leak in mc_pcie_init_irq_domains()
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit f030304fdeb87ec8f1b518c73703214aec6cc24a ]
of_get_next_child() returns a node pointer with refcount incremented, so we should use of_node_put() on it when we don't need it anymore.
mc_pcie_init_irq_domains() only calls of_node_put() in the normal path, missing it in some error paths. Add missing of_node_put() to avoid refcount leak.
--- drivers/pci/controller/pcie-microchip-host.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/pci/controller/pcie-microchip-host.c +2 -0
@@ -894,6 +894,7 @@ static int mc_pcie_init_irq_domains(struct mc_port *port) &event_domain_ops, port);if (!port->event_domain) {dev_err (dev,"failed to get event domain\n" ); +of_node_put (pcie_intc_node);return -ENOMEM ; }
@@ -903,6 +904,7 @@ static int mc_pcie_init_irq_domains(struct mc_port *port) &intx_domain_ops, port);if (!port->intx_domain) {dev_err (dev,"failed to get an INTx IRQ domain\n" ); +of_node_put (pcie_intc_node);return -ENOMEM ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 406/779 PCI: tegra194: Fix PM error handling in tegra_pcie_config_ep()
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit e8fbd344a5ea62663554b8546b6bf9f88b93785a ]
pm_runtime_enable() will increase power disable depth. If dw_pcie_ep_init() fails, we should use pm_runtime_disable() to balance it with pm_runtime_enable().
Add missing pm_runtime_disable() for tegra_pcie_config_ep().
--- drivers/pci/controller/dwc/pcie-tegra194.c | 1 + 1 file changed, 1 insertion(+)
drivers/pci/controller/dwc/pcie-tegra194.c +1 -0
@@ -1951,6 +1951,7 @@ static int tegra_pcie_config_ep(struct tegra_pcie_dw *pcie,if (ret) {dev_err (dev,"Failed to initialize DWC Endpoint subsystem: %d\n" , ret); +pm_runtime_disable (dev);return ret; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 407/779 HID: cp2112: prevent a buffer overflow in cp2112_xfer()
In reply to Greg Kroah-HartmanFrom: Harshit Mogalapalli <[email protected]>
[ Upstream commit 381583845d19cb4bd21c8193449385f3fefa9caf ]
Smatch warnings:drivers/hid/hid-cp2112.c:793 cp2112_xfer() error: __memcpy() 'data->block[1]' too small (33 vs 255) drivers/hid/hid-cp2112.c:793 cp2112_xfer() error: __memcpy() 'buf' too small (64 vs 255)
The 'read_length' variable is provided by 'data->block[0]' which comes from user and it(read_length) can take a value between 0-255. Add an upper bound to 'read_length' variable to prevent a buffer overflow in memcpy().
--- drivers/hid/hid-cp2112.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/hid/hid-cp2112.c +5 -0
@@ -788,6 +788,11 @@ static int cp2112_xfer(struct i2c_adapter *adap, u16 addr, data->word =le16_to_cpup ((__le16 *)buf);break ;case I2C_SMBUS_I2C_BLOCK_DATA : +if (read_length >I2C_SMBUS_BLOCK_MAX ) { + ret = -EINVAL ; + goto power_normal; + } +memcpy (data->block +1 , buf, read_length);break ;case I2C_SMBUS_BLOCK_DATA :
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 408/779 mtd: sm_ftl: Fix deadlock caused by cancel_work_sync in sm_release
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
[ Upstream commit a61528d997619a518ee8c51cf0ef0513021afaff ]
There is a deadlock between sm_release and sm_cache_flush_work which is a work item. The cancel_work_sync in sm_release will not return until sm_cache_flush_work is finished. If we hold mutex_lock and use cancel_work_sync to wait the work item to finish, the work item also requires mutex_lock. As a result, the sm_release will be blocked forever. The race condition is shown below:
(Thread 1) | (Thread 2)
sm_release |
mutex_lock(&ftl->mutex) | sm_cache_flush_work
| mutex_lock(&ftl->mutex)
cancel_work_sync | ...This patch moves del_timer_sync and cancel_work_sync out of mutex_lock in order to mitigate deadlock.
--- drivers/mtd/sm_ftl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mtd/sm_ftl.c +1 -1
@@ -1111,9 +1111,9 @@ static void sm_release(struct mtd_blktrans_dev *dev) {struct sm_ftl *ftl = dev->priv; -mutex_lock (&ftl->mutex);del_timer_sync (&ftl->timer);cancel_work_sync (&ftl->flush_work); +mutex_lock (&ftl->mutex);sm_cache_flush (ftl);mutex_unlock (&ftl->mutex); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 409/779 mtd: partitions: Fix refcount leak in parse_redboot_of
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit 9f7e62815cf3cbbcb1b8cb21649fb4dfdb3aa016 ]
of_get_child_by_name() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak.
--- drivers/mtd/parsers/redboot.c | 1 + 1 file changed, 1 insertion(+)
drivers/mtd/parsers/redboot.c +1 -0
@@ -58,6 +58,7 @@ static void parse_redboot_of(struct mtd_info *master)return ; ret =of_property_read_u32 (npart,"fis-index-block" , &dirblock); +of_node_put (npart);if (ret)return ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 410/779 mtd: parsers: ofpart: Fix refcount leak in bcm4908_partitions_fw_offset
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit e607879b0da18c451de5e91daf239cc2f2f8ff2d ]
of_find_node_by_path() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore.
Add missing of_node_put() to avoid refcount leak.
--- drivers/mtd/parsers/ofpart_bcm4908.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/mtd/parsers/ofpart_bcm4908.c +3 -0
@@ -35,12 +35,15 @@ static long long bcm4908_partitions_fw_offset(void) err =kstrtoul (s + len +1 ,0 , &offset);if (err) {pr_err ("failed to parse %s\n" , s + len +1 ); +of_node_put (root);return err; } +of_node_put (root);return offset <<10 ; } +of_node_put (root);return -ENOENT ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 411/779 mtd: st_spi_fsm: Add a clk_disable_unprepare() in .probe()s error path
In reply to Greg Kroah-HartmanFrom: Uwe Kleine-König <[email protected]>
[ Upstream commit 28607b426c3d050714f250d0faeb99d2e9106e90 ]
For all but one error path clk_disable_unprepare() is already there. Add it to the one location where it's missing.
--- drivers/mtd/devices/st_spi_fsm.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/mtd/devices/st_spi_fsm.c +5 -3
@@ -2115,10 +2115,12 @@ static int stfsm_probe(struct platform_device *pdev) (long long )fsm->mtd.size, (long long )(fsm->mtd.size >>20 ), fsm->mtd.erasesize, (fsm->mtd.erasesize >> 10)); -return mtd_device_register (&fsm->mtd,NULL ,0 ); - + ret =mtd_device_register (&fsm->mtd,NULL ,0 ); +if (ret) { err_clk_unprepare: -clk_disable_unprepare (fsm->clk); +clk_disable_unprepare (fsm->clk); + } +return ret; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 412/779 PCI: mediatek-gen3: Fix refcount leak in mtk_pcie_init_irq_domains()
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit bf038503d5fe90189743124233fe7aeb0984e961 ]
of_get_child_by_name() returns a node pointer with refcount incremented, so we should use of_node_put() on it when we don't need it anymore.
Add missing of_node_put() to avoid refcount leak.
--- drivers/pci/controller/pcie-mediatek-gen3.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/pci/controller/pcie-mediatek-gen3.c +5 -1
@@ -600,7 +600,8 @@ static int mtk_pcie_init_irq_domains(struct mtk_pcie_port *port) &intx_domain_ops, port);if (!port->intx_domain) {dev_err (dev,"failed to create INTx IRQ domain\n" ); -return -ENODEV ; + ret = -ENODEV ; + goto out_put_node; }/* Setup MSI */
@@ -623,6 +624,7 @@ static int mtk_pcie_init_irq_domains(struct mtk_pcie_port *port) goto err_msi_domain; } +of_node_put (intc_node);return 0 ; err_msi_domain:
@@ -630,6 +632,8 @@ static int mtk_pcie_init_irq_domains(struct mtk_pcie_port *port) err_msi_bottom_domain:irq_domain_remove (port->intx_domain); +out_put_node: +of_node_put (intc_node);return ret; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 413/779 fpga: altera-pr-ip: fix unsigned comparison with less than zero
In reply to Greg Kroah-HartmanFrom: Marco Pagani <[email protected]>
[ Upstream commit 2df84a757d87fd62869fc401119d429735377ec5 ]
Fix the "comparison with less than zero" warning reported by cppcheck for the unsigned (size_t) parameter count of the alt_pr_fpga_write() function.
--- drivers/fpga/altera-pr-ip-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/fpga/altera-pr-ip-core.c +1 -1
@@ -108,7 +108,7 @@ static int alt_pr_fpga_write(struct fpga_manager *mgr, const char *buf,u32 *buffer_32 = (u32 *)buf;size_t i =0 ; -if (count <=0 ) +if (!count)return -EINVAL ;/* Write out the complete 32-bit chunks */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 414/779 usb: host: Fix refcount leak in ehci_hcd_ppc_of_probe
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit b5c5b13cb45e2c88181308186b0001992cb41954 ]
of_find_compatible_node() returns a node pointer with refcount incremented, we should use of_node_put() on it when done. Add missing of_node_put() to avoid refcount leak.
--- drivers/usb/host/ehci-ppc-of.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/host/ehci-ppc-of.c +1 -0
@@ -148,6 +148,7 @@ static int ehci_hcd_ppc_of_probe(struct platform_device *op) }else { ehci->has_amcc_usb23 =1 ; } +of_node_put (np); }if (of_get_property (dn,"big-endian" ,NULL )) {
Signature · 1 line
2.35.1