* [PATCH v1] mtd: rawnand: meson: check buffer length
@ 2023-06-05 19:10 Arseniy Krasnov
2023-06-06 7:16 ` Miquel Raynal
0 siblings, 1 reply; 4+ messages in thread
From: Arseniy Krasnov @ 2023-06-05 19:10 UTC (permalink / raw)
To: Liang Yang, Miquel Raynal, Richard Weinberger,
Vignesh Raghavendra, Neil Armstrong, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl
Cc: oxffffaa, kernel, Arseniy Krasnov, linux-mtd, linux-arm-kernel,
linux-amlogic, linux-kernel
Meson NAND controller has limited buffer length, so check it before
command execution to avoid length trim. Also check MTD write size on
chip attach.
Signed-off-by: Arseniy Krasnov <AVKrasnov@sberdevices.ru>
---
drivers/mtd/nand/raw/meson_nand.c | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
index 074e14225c06..bfb5363cac23 100644
--- a/drivers/mtd/nand/raw/meson_nand.c
+++ b/drivers/mtd/nand/raw/meson_nand.c
@@ -108,6 +108,8 @@
#define PER_INFO_BYTE 8
+#define NFC_CMD_RAW_LEN GENMASK(13, 0)
+
struct meson_nfc_nand_chip {
struct list_head node;
struct nand_chip nand;
@@ -280,7 +282,7 @@ static void meson_nfc_cmd_access(struct nand_chip *nand, int raw, bool dir,
if (raw) {
len = mtd->writesize + mtd->oobsize;
- cmd = (len & GENMASK(13, 0)) | scrambler | DMA_DIR(dir);
+ cmd = len | scrambler | DMA_DIR(dir);
writel(cmd, nfc->reg_base + NFC_REG_CMD);
return;
}
@@ -544,7 +546,7 @@ static int meson_nfc_read_buf(struct nand_chip *nand, u8 *buf, int len)
if (ret)
goto out;
- cmd = NFC_CMD_N2M | (len & GENMASK(13, 0));
+ cmd = NFC_CMD_N2M | len;
writel(cmd, nfc->reg_base + NFC_REG_CMD);
meson_nfc_drain_cmd(nfc);
@@ -568,7 +570,7 @@ static int meson_nfc_write_buf(struct nand_chip *nand, u8 *buf, int len)
if (ret)
return ret;
- cmd = NFC_CMD_M2N | (len & GENMASK(13, 0));
+ cmd = NFC_CMD_M2N | len;
writel(cmd, nfc->reg_base + NFC_REG_CMD);
meson_nfc_drain_cmd(nfc);
@@ -936,6 +938,9 @@ static int meson_nfc_exec_op(struct nand_chip *nand,
break;
case NAND_OP_DATA_IN_INSTR:
+ if (instr->ctx.data.len > NFC_CMD_RAW_LEN)
+ return -EINVAL;
+
buf = meson_nand_op_get_dma_safe_input_buf(instr);
if (!buf)
return -ENOMEM;
@@ -944,6 +949,9 @@ static int meson_nfc_exec_op(struct nand_chip *nand,
break;
case NAND_OP_DATA_OUT_INSTR:
+ if (instr->ctx.data.len > NFC_CMD_RAW_LEN)
+ return -EINVAL;
+
buf = meson_nand_op_get_dma_safe_output_buf(instr);
if (!buf)
return -ENOMEM;
@@ -1181,6 +1189,7 @@ static int meson_nand_attach_chip(struct nand_chip *nand)
struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
struct mtd_info *mtd = nand_to_mtd(nand);
int nsectors = mtd->writesize / 1024;
+ int raw_writesize;
int ret;
if (!mtd->name) {
@@ -1192,6 +1201,13 @@ static int meson_nand_attach_chip(struct nand_chip *nand)
return -ENOMEM;
}
+ raw_writesize = mtd->writesize + mtd->oobsize;
+ if (raw_writesize > NFC_CMD_RAW_LEN) {
+ dev_err(nfc->dev, "too big write size in raw mode: %d > %ld\n",
+ raw_writesize, NFC_CMD_RAW_LEN);
+ return -EINVAL;
+ }
+
if (nand->bbt_options & NAND_BBT_USE_FLASH)
nand->bbt_options |= NAND_BBT_NO_OOB;
--
2.35.0
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH v1] mtd: rawnand: meson: check buffer length
2023-06-05 19:10 [PATCH v1] mtd: rawnand: meson: check buffer length Arseniy Krasnov
@ 2023-06-06 7:16 ` Miquel Raynal
2023-06-06 7:37 ` Arseniy Krasnov
0 siblings, 1 reply; 4+ messages in thread
From: Miquel Raynal @ 2023-06-06 7:16 UTC (permalink / raw)
To: Arseniy Krasnov
Cc: Liang Yang, Richard Weinberger, Vignesh Raghavendra,
Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
oxffffaa, kernel, linux-mtd, linux-arm-kernel, linux-amlogic,
linux-kernel
Hi Arseniy,
AVKrasnov@sberdevices.ru wrote on Mon, 5 Jun 2023 22:10:46 +0300:
> Meson NAND controller has limited buffer length, so check it before
> command execution to avoid length trim. Also check MTD write size on
> chip attach.
Almost there :)
>
> Signed-off-by: Arseniy Krasnov <AVKrasnov@sberdevices.ru>
> ---
> drivers/mtd/nand/raw/meson_nand.c | 22 +++++++++++++++++++---
> 1 file changed, 19 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
> index 074e14225c06..bfb5363cac23 100644
> --- a/drivers/mtd/nand/raw/meson_nand.c
> +++ b/drivers/mtd/nand/raw/meson_nand.c
> @@ -108,6 +108,8 @@
>
> #define PER_INFO_BYTE 8
>
> +#define NFC_CMD_RAW_LEN GENMASK(13, 0)
> +
> struct meson_nfc_nand_chip {
> struct list_head node;
> struct nand_chip nand;
> @@ -280,7 +282,7 @@ static void meson_nfc_cmd_access(struct nand_chip *nand, int raw, bool dir,
>
> if (raw) {
> len = mtd->writesize + mtd->oobsize;
> - cmd = (len & GENMASK(13, 0)) | scrambler | DMA_DIR(dir);
> + cmd = len | scrambler | DMA_DIR(dir);
> writel(cmd, nfc->reg_base + NFC_REG_CMD);
> return;
> }
> @@ -544,7 +546,7 @@ static int meson_nfc_read_buf(struct nand_chip *nand, u8 *buf, int len)
> if (ret)
> goto out;
>
> - cmd = NFC_CMD_N2M | (len & GENMASK(13, 0));
> + cmd = NFC_CMD_N2M | len;
> writel(cmd, nfc->reg_base + NFC_REG_CMD);
>
> meson_nfc_drain_cmd(nfc);
> @@ -568,7 +570,7 @@ static int meson_nfc_write_buf(struct nand_chip *nand, u8 *buf, int len)
> if (ret)
> return ret;
>
> - cmd = NFC_CMD_M2N | (len & GENMASK(13, 0));
> + cmd = NFC_CMD_M2N | len;
> writel(cmd, nfc->reg_base + NFC_REG_CMD);
>
> meson_nfc_drain_cmd(nfc);
> @@ -936,6 +938,9 @@ static int meson_nfc_exec_op(struct nand_chip *nand,
> break;
>
> case NAND_OP_DATA_IN_INSTR:
> + if (instr->ctx.data.len > NFC_CMD_RAW_LEN)
> + return -EINVAL;
You need to refuse the operation earlier. That's what the check_op
boolean is about. Maybe you can take inspiration from anfc_check_op()
in the arasan controller.
> +
> buf = meson_nand_op_get_dma_safe_input_buf(instr);
> if (!buf)
> return -ENOMEM;
> @@ -944,6 +949,9 @@ static int meson_nfc_exec_op(struct nand_chip *nand,
> break;
>
> case NAND_OP_DATA_OUT_INSTR:
> + if (instr->ctx.data.len > NFC_CMD_RAW_LEN)
> + return -EINVAL;
Same.
> +
> buf = meson_nand_op_get_dma_safe_output_buf(instr);
> if (!buf)
> return -ENOMEM;
> @@ -1181,6 +1189,7 @@ static int meson_nand_attach_chip(struct nand_chip *nand)
> struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
> struct mtd_info *mtd = nand_to_mtd(nand);
> int nsectors = mtd->writesize / 1024;
> + int raw_writesize;
> int ret;
>
> if (!mtd->name) {
> @@ -1192,6 +1201,13 @@ static int meson_nand_attach_chip(struct nand_chip *nand)
> return -ENOMEM;
> }
>
> + raw_writesize = mtd->writesize + mtd->oobsize;
> + if (raw_writesize > NFC_CMD_RAW_LEN) {
> + dev_err(nfc->dev, "too big write size in raw mode: %d > %ld\n",
> + raw_writesize, NFC_CMD_RAW_LEN);
> + return -EINVAL;
> + }
> +
> if (nand->bbt_options & NAND_BBT_USE_FLASH)
> nand->bbt_options |= NAND_BBT_NO_OOB;
>
Thanks,
Miquèl
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH v1] mtd: rawnand: meson: check buffer length
2023-06-06 7:16 ` Miquel Raynal
@ 2023-06-06 7:37 ` Arseniy Krasnov
2023-06-06 7:50 ` Miquel Raynal
0 siblings, 1 reply; 4+ messages in thread
From: Arseniy Krasnov @ 2023-06-06 7:37 UTC (permalink / raw)
To: Miquel Raynal
Cc: Liang Yang, Richard Weinberger, Vignesh Raghavendra,
Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
oxffffaa, kernel, linux-mtd, linux-arm-kernel, linux-amlogic,
linux-kernel
On 06.06.2023 10:16, Miquel Raynal wrote:
> Hi Arseniy,
>
> AVKrasnov@sberdevices.ru wrote on Mon, 5 Jun 2023 22:10:46 +0300:
>
>> Meson NAND controller has limited buffer length, so check it before
>> command execution to avoid length trim. Also check MTD write size on
>> chip attach.
>
> Almost there :)
Hello Miquel!
You mean to rephrase it? :)
Thanks, Arseniy
>
>>
>> Signed-off-by: Arseniy Krasnov <AVKrasnov@sberdevices.ru>
>> ---
>> drivers/mtd/nand/raw/meson_nand.c | 22 +++++++++++++++++++---
>> 1 file changed, 19 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
>> index 074e14225c06..bfb5363cac23 100644
>> --- a/drivers/mtd/nand/raw/meson_nand.c
>> +++ b/drivers/mtd/nand/raw/meson_nand.c
>> @@ -108,6 +108,8 @@
>>
>> #define PER_INFO_BYTE 8
>>
>> +#define NFC_CMD_RAW_LEN GENMASK(13, 0)
>> +
>> struct meson_nfc_nand_chip {
>> struct list_head node;
>> struct nand_chip nand;
>> @@ -280,7 +282,7 @@ static void meson_nfc_cmd_access(struct nand_chip *nand, int raw, bool dir,
>>
>> if (raw) {
>> len = mtd->writesize + mtd->oobsize;
>> - cmd = (len & GENMASK(13, 0)) | scrambler | DMA_DIR(dir);
>> + cmd = len | scrambler | DMA_DIR(dir);
>> writel(cmd, nfc->reg_base + NFC_REG_CMD);
>> return;
>> }
>> @@ -544,7 +546,7 @@ static int meson_nfc_read_buf(struct nand_chip *nand, u8 *buf, int len)
>> if (ret)
>> goto out;
>>
>> - cmd = NFC_CMD_N2M | (len & GENMASK(13, 0));
>> + cmd = NFC_CMD_N2M | len;
>> writel(cmd, nfc->reg_base + NFC_REG_CMD);
>>
>> meson_nfc_drain_cmd(nfc);
>> @@ -568,7 +570,7 @@ static int meson_nfc_write_buf(struct nand_chip *nand, u8 *buf, int len)
>> if (ret)
>> return ret;
>>
>> - cmd = NFC_CMD_M2N | (len & GENMASK(13, 0));
>> + cmd = NFC_CMD_M2N | len;
>> writel(cmd, nfc->reg_base + NFC_REG_CMD);
>>
>> meson_nfc_drain_cmd(nfc);
>> @@ -936,6 +938,9 @@ static int meson_nfc_exec_op(struct nand_chip *nand,
>> break;
>>
>> case NAND_OP_DATA_IN_INSTR:
>> + if (instr->ctx.data.len > NFC_CMD_RAW_LEN)
>> + return -EINVAL;
>
> You need to refuse the operation earlier. That's what the check_op
> boolean is about. Maybe you can take inspiration from anfc_check_op()
> in the arasan controller.
Ok! Thanks!
>
>> +
>> buf = meson_nand_op_get_dma_safe_input_buf(instr);
>> if (!buf)
>> return -ENOMEM;
>> @@ -944,6 +949,9 @@ static int meson_nfc_exec_op(struct nand_chip *nand,
>> break;
>>
>> case NAND_OP_DATA_OUT_INSTR:
>> + if (instr->ctx.data.len > NFC_CMD_RAW_LEN)
>> + return -EINVAL;
>
> Same.
>
>> +
>> buf = meson_nand_op_get_dma_safe_output_buf(instr);
>> if (!buf)
>> return -ENOMEM;
>> @@ -1181,6 +1189,7 @@ static int meson_nand_attach_chip(struct nand_chip *nand)
>> struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
>> struct mtd_info *mtd = nand_to_mtd(nand);
>> int nsectors = mtd->writesize / 1024;
>> + int raw_writesize;
>> int ret;
>>
>> if (!mtd->name) {
>> @@ -1192,6 +1201,13 @@ static int meson_nand_attach_chip(struct nand_chip *nand)
>> return -ENOMEM;
>> }
>>
>> + raw_writesize = mtd->writesize + mtd->oobsize;
>> + if (raw_writesize > NFC_CMD_RAW_LEN) {
>> + dev_err(nfc->dev, "too big write size in raw mode: %d > %ld\n",
>> + raw_writesize, NFC_CMD_RAW_LEN);
>> + return -EINVAL;
>> + }
>> +
>> if (nand->bbt_options & NAND_BBT_USE_FLASH)
>> nand->bbt_options |= NAND_BBT_NO_OOB;
>>
>
>
> Thanks,
> Miquèl
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH v1] mtd: rawnand: meson: check buffer length
2023-06-06 7:37 ` Arseniy Krasnov
@ 2023-06-06 7:50 ` Miquel Raynal
0 siblings, 0 replies; 4+ messages in thread
From: Miquel Raynal @ 2023-06-06 7:50 UTC (permalink / raw)
To: Arseniy Krasnov
Cc: Liang Yang, Richard Weinberger, Vignesh Raghavendra,
Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
oxffffaa, kernel, linux-mtd, linux-arm-kernel, linux-amlogic,
linux-kernel
Hi Arseniy,
avkrasnov@sberdevices.ru wrote on Tue, 6 Jun 2023 10:37:43 +0300:
> On 06.06.2023 10:16, Miquel Raynal wrote:
> > Hi Arseniy,
> >
> > AVKrasnov@sberdevices.ru wrote on Mon, 5 Jun 2023 22:10:46 +0300:
> >
> >> Meson NAND controller has limited buffer length, so check it before
> >> command execution to avoid length trim. Also check MTD write size on
> >> chip attach.
> >
> > Almost there :)
>
> Hello Miquel!
>
> You mean to rephrase it? :)
Not at all, I meant: there is something to change in this file (see
below) but the patch is close to be ready.
>
> Thanks, Arseniy
>
> >
> >>
> >> Signed-off-by: Arseniy Krasnov <AVKrasnov@sberdevices.ru>
> >> ---
> >> drivers/mtd/nand/raw/meson_nand.c | 22 +++++++++++++++++++---
> >> 1 file changed, 19 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
> >> index 074e14225c06..bfb5363cac23 100644
> >> --- a/drivers/mtd/nand/raw/meson_nand.c
> >> +++ b/drivers/mtd/nand/raw/meson_nand.c
> >> @@ -108,6 +108,8 @@
> >>
> >> #define PER_INFO_BYTE 8
> >>
> >> +#define NFC_CMD_RAW_LEN GENMASK(13, 0)
> >> +
> >> struct meson_nfc_nand_chip {
> >> struct list_head node;
> >> struct nand_chip nand;
> >> @@ -280,7 +282,7 @@ static void meson_nfc_cmd_access(struct nand_chip *nand, int raw, bool dir,
> >>
> >> if (raw) {
> >> len = mtd->writesize + mtd->oobsize;
> >> - cmd = (len & GENMASK(13, 0)) | scrambler | DMA_DIR(dir);
> >> + cmd = len | scrambler | DMA_DIR(dir);
> >> writel(cmd, nfc->reg_base + NFC_REG_CMD);
> >> return;
> >> }
> >> @@ -544,7 +546,7 @@ static int meson_nfc_read_buf(struct nand_chip *nand, u8 *buf, int len)
> >> if (ret)
> >> goto out;
> >>
> >> - cmd = NFC_CMD_N2M | (len & GENMASK(13, 0));
> >> + cmd = NFC_CMD_N2M | len;
> >> writel(cmd, nfc->reg_base + NFC_REG_CMD);
> >>
> >> meson_nfc_drain_cmd(nfc);
> >> @@ -568,7 +570,7 @@ static int meson_nfc_write_buf(struct nand_chip *nand, u8 *buf, int len)
> >> if (ret)
> >> return ret;
> >>
> >> - cmd = NFC_CMD_M2N | (len & GENMASK(13, 0));
> >> + cmd = NFC_CMD_M2N | len;
> >> writel(cmd, nfc->reg_base + NFC_REG_CMD);
> >>
> >> meson_nfc_drain_cmd(nfc);
> >> @@ -936,6 +938,9 @@ static int meson_nfc_exec_op(struct nand_chip *nand,
> >> break;
> >>
> >> case NAND_OP_DATA_IN_INSTR:
> >> + if (instr->ctx.data.len > NFC_CMD_RAW_LEN)
> >> + return -EINVAL;
> >
> > You need to refuse the operation earlier. That's what the check_op
> > boolean is about. Maybe you can take inspiration from anfc_check_op()
> > in the arasan controller.
>
> Ok! Thanks!
>
> >
> >> +
> >> buf = meson_nand_op_get_dma_safe_input_buf(instr);
> >> if (!buf)
> >> return -ENOMEM;
> >> @@ -944,6 +949,9 @@ static int meson_nfc_exec_op(struct nand_chip *nand,
> >> break;
> >>
> >> case NAND_OP_DATA_OUT_INSTR:
> >> + if (instr->ctx.data.len > NFC_CMD_RAW_LEN)
> >> + return -EINVAL;
> >
> > Same.
> >
> >> +
> >> buf = meson_nand_op_get_dma_safe_output_buf(instr);
> >> if (!buf)
> >> return -ENOMEM;
> >> @@ -1181,6 +1189,7 @@ static int meson_nand_attach_chip(struct nand_chip *nand)
> >> struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
> >> struct mtd_info *mtd = nand_to_mtd(nand);
> >> int nsectors = mtd->writesize / 1024;
> >> + int raw_writesize;
> >> int ret;
> >>
> >> if (!mtd->name) {
> >> @@ -1192,6 +1201,13 @@ static int meson_nand_attach_chip(struct nand_chip *nand)
> >> return -ENOMEM;
> >> }
> >>
> >> + raw_writesize = mtd->writesize + mtd->oobsize;
> >> + if (raw_writesize > NFC_CMD_RAW_LEN) {
> >> + dev_err(nfc->dev, "too big write size in raw mode: %d > %ld\n",
> >> + raw_writesize, NFC_CMD_RAW_LEN);
> >> + return -EINVAL;
> >> + }
> >> +
> >> if (nand->bbt_options & NAND_BBT_USE_FLASH)
> >> nand->bbt_options |= NAND_BBT_NO_OOB;
> >>
> >
> >
> > Thanks,
> > Miquèl
Thanks,
Miquèl
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2023-06-06 8:51 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-06-05 19:10 [PATCH v1] mtd: rawnand: meson: check buffer length Arseniy Krasnov
2023-06-06 7:16 ` Miquel Raynal
2023-06-06 7:37 ` Arseniy Krasnov
2023-06-06 7:50 ` Miquel Raynal
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).