linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Corentin Labbe <clabbe.montjoie@gmail.com>
To: Thomas Gleixner <tglx@linutronix.de>
Cc: herbert@gondor.apana.org.au, mripard@kernel.org, wens@csie.org,
	linux-arm-kernel@lists.infradead.org,
	linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org,
	Jens Axboe <axboe@kernel.dk>,
	linux-mm@kvack.org, Andrew Morton <akpm@linuxfoundation.org>,
	Julia Lawall <julia.lawall@lip6.fr>,
	Matthew Wilcox <willy@infradead.org>
Subject: Re: crypto: sun4i-ss: error with kmap
Date: Mon, 7 Dec 2020 13:18:20 +0100	[thread overview]
Message-ID: <20201207121820.GB8458@Red> (raw)
In-Reply-To: <87ft4i79oq.fsf@nanos.tec.linutronix.de>

On Mon, Dec 07, 2020 at 01:15:49AM +0100, Thomas Gleixner wrote:
> On Sun, Dec 06 2020 at 22:40, Corentin Labbe wrote:
> > On Sat, Dec 05, 2020 at 08:48:15PM +0100, Thomas Gleixner wrote:
> >> So this maps two pages and unmaps the first one. That's all called from
> >> sun4i_ss_opti_poll() and the bug is clearly visible there:
> >> 
> >> 	sg_miter_next(&mi);
> >> 	sg_miter_next(&mo);
> >> 
> >> release_ss:
> >> 	sg_miter_stop(&mi);
> >> 	sg_miter_stop(&mo);
> >> 
> >> Written by yourself :) Same issue in sun4i_ss_cipher_poll()
> >> 
> >> Fix below.
> >> 
> >
> > Unfortunatly, the crash still happen with the fix.
> > See http://kernel.montjoie.ovh/131321.log
> 
> And why are you not looking for the reason of this problem in your own
> code yourself? It's not a regression caused by my work.
> 
> Turn on CONFIG_DEBUG_HIGHMEM on 5.10-rcX or older kernels and you will
> get the very same crashes. My work just made these checks unconditional.
> 
> This was broken forever and it's not my problem that you did not enable
> mandatory debug options when developing this thing.
> 
> I gave you tons of hints by now how to debug this and what to look
> for. Obviously I overlooked something and here is the final hint:
> 
>  	sg_miter_next(&mi);
>  	sg_miter_next(&mo);
> 
>         do {
>            ....
>            if (cond1)
>                sg_miter_next(&mi);      <--- HINT
>            ....
>            if (cond2)
>                sg_miter_next(&mo);
>  
> release_ss:
>  	sg_miter_stop(&mi);
>  	sg_miter_stop(&mo);
> 
> So yes, I overlooked the obvious, but as I said above it's not something
> which my is failing due to my changes. It was broken forever, it just
> was not tested properly. Don't blame the messenger.
> 

Hello

I wasnt blaming you, I set you in TO: since you worked on kmap recently just in case of.
I tryed to debug myself, but since it worked before I was sure the problem was outside my code.

So if I understand correctly, basicly I cannot have two atomic kmap at the same time since it made unmapping them in the right order complex.

I am not sure to have well understood your hint, but could you give me what you think about the following patch which fix (at least) the crash.
Instead of holding SGmiter (and so two kmap), I use only one at a time.

Thanks for your help.

diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
index 99a415e8a13c..4f25e76dc269 100644
--- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
+++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
@@ -36,6 +36,8 @@ static int noinline_for_stack sun4i_ss_opti_poll(struct skcipher_request *areq)
 	unsigned long flags;
 	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
 	struct sun4i_ss_alg_template *algt;
+	unsigned long toi = 0, too = 0;
+	bool miter_err;
 
 	if (!areq->cryptlen)
 		return 0;
@@ -71,39 +73,51 @@ static int noinline_for_stack sun4i_ss_opti_poll(struct skcipher_request *areq)
 	}
 	writel(mode, ss->base + SS_CTL);
 
-	sg_miter_start(&mi, areq->src, sg_nents(areq->src),
-		       SG_MITER_FROM_SG | SG_MITER_ATOMIC);
-	sg_miter_start(&mo, areq->dst, sg_nents(areq->dst),
-		       SG_MITER_TO_SG | SG_MITER_ATOMIC);
-	sg_miter_next(&mi);
-	sg_miter_next(&mo);
-	if (!mi.addr || !mo.addr) {
-		dev_err_ratelimited(ss->dev, "ERROR: sg_miter return null\n");
-		err = -EINVAL;
-		goto release_ss;
-	}
 
 	ileft = areq->cryptlen / 4;
 	oleft = areq->cryptlen / 4;
 	oi = 0;
 	oo = 0;
 	do {
-		todo = min(rx_cnt, ileft);
-		todo = min_t(size_t, todo, (mi.length - oi) / 4);
-		if (todo) {
-			ileft -= todo;
-			writesl(ss->base + SS_RXFIFO, mi.addr + oi, todo);
-			oi += todo * 4;
-		}
-		if (oi == mi.length) {
-			sg_miter_next(&mi);
-			oi = 0;
+		if (ileft) {
+			sg_miter_start(&mi, areq->src, sg_nents(areq->src),
+					SG_MITER_FROM_SG | SG_MITER_ATOMIC);
+			if (toi)
+				sg_miter_skip(&mi, toi);
+			miter_err = sg_miter_next(&mi);
+			if (!miter_err || !mi.addr) {
+				dev_err_ratelimited(ss->dev, "ERROR: sg_miter return null\n");
+				err = -EINVAL;
+				goto release_ss;
+			}
+			todo = min(rx_cnt, ileft);
+			todo = min_t(size_t, todo, (mi.length - oi) / 4);
+			if (todo) {
+				ileft -= todo;
+				writesl(ss->base + SS_RXFIFO, mi.addr + oi, todo);
+				oi += todo * 4;
+			}
+			if (oi == mi.length) {
+				toi += mi.length;
+				oi = 0;
+			}
+			sg_miter_stop(&mi);
 		}
 
 		spaces = readl(ss->base + SS_FCSR);
 		rx_cnt = SS_RXFIFO_SPACES(spaces);
 		tx_cnt = SS_TXFIFO_SPACES(spaces);
 
+		sg_miter_start(&mo, areq->dst, sg_nents(areq->dst),
+			       SG_MITER_TO_SG | SG_MITER_ATOMIC);
+		if (too)
+			sg_miter_skip(&mo, too);
+		miter_err = sg_miter_next(&mo);
+		if (!miter_err || !mo.addr) {
+			dev_err_ratelimited(ss->dev, "ERROR: sg_miter return null\n");
+			err = -EINVAL;
+			goto release_ss;
+		}
 		todo = min(tx_cnt, oleft);
 		todo = min_t(size_t, todo, (mo.length - oo) / 4);
 		if (todo) {
@@ -112,9 +126,10 @@ static int noinline_for_stack sun4i_ss_opti_poll(struct skcipher_request *areq)
 			oo += todo * 4;
 		}
 		if (oo == mo.length) {
-			sg_miter_next(&mo);
 			oo = 0;
+			too += mo.length;
 		}
+		sg_miter_stop(&mo);
 	} while (oleft);
 
 	if (areq->iv) {
@@ -128,8 +143,6 @@ static int noinline_for_stack sun4i_ss_opti_poll(struct skcipher_request *areq)
 	}
 
 release_ss:
-	sg_miter_stop(&mo);
-	sg_miter_stop(&mi);
 	writel(0, ss->base + SS_CTL);
 	spin_unlock_irqrestore(&ss->slock, flags);
 	return err;
@@ -194,6 +207,8 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
 	unsigned int obl = 0;	/* length of data in bufo */
 	unsigned long flags;
 	bool need_fallback = false;
+	unsigned long toi = 0, too = 0;
+	bool miter_err;
 
 	if (!areq->cryptlen)
 		return 0;
@@ -253,17 +268,6 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
 	}
 	writel(mode, ss->base + SS_CTL);
 
-	sg_miter_start(&mi, areq->src, sg_nents(areq->src),
-		       SG_MITER_FROM_SG | SG_MITER_ATOMIC);
-	sg_miter_start(&mo, areq->dst, sg_nents(areq->dst),
-		       SG_MITER_TO_SG | SG_MITER_ATOMIC);
-	sg_miter_next(&mi);
-	sg_miter_next(&mo);
-	if (!mi.addr || !mo.addr) {
-		dev_err_ratelimited(ss->dev, "ERROR: sg_miter return null\n");
-		err = -EINVAL;
-		goto release_ss;
-	}
 	ileft = areq->cryptlen;
 	oleft = areq->cryptlen;
 	oi = 0;
@@ -271,6 +275,16 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
 
 	while (oleft) {
 		if (ileft) {
+			sg_miter_start(&mi, areq->src, sg_nents(areq->src),
+				       SG_MITER_FROM_SG | SG_MITER_ATOMIC);
+			if (toi)
+				sg_miter_skip(&mi, toi);
+			miter_err = sg_miter_next(&mi);
+			if (!miter_err || !mi.addr) {
+				dev_err_ratelimited(ss->dev, "ERROR: sg_miter return null\n");
+				err = -EINVAL;
+				goto release_ss;
+			}
 			/*
 			 * todo is the number of consecutive 4byte word that we
 			 * can read from current SG
@@ -303,31 +317,38 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
 				}
 			}
 			if (oi == mi.length) {
-				sg_miter_next(&mi);
+				toi += mi.length;
 				oi = 0;
 			}
+			sg_miter_stop(&mi);
 		}
 
 		spaces = readl(ss->base + SS_FCSR);
 		rx_cnt = SS_RXFIFO_SPACES(spaces);
 		tx_cnt = SS_TXFIFO_SPACES(spaces);
-		dev_dbg(ss->dev,
-			"%x %u/%zu %u/%u cnt=%u %u/%zu %u/%u cnt=%u %u\n",
-			mode,
-			oi, mi.length, ileft, areq->cryptlen, rx_cnt,
-			oo, mo.length, oleft, areq->cryptlen, tx_cnt, ob);
 
 		if (!tx_cnt)
 			continue;
+		sg_miter_start(&mo, areq->dst, sg_nents(areq->dst),
+			       SG_MITER_TO_SG | SG_MITER_ATOMIC);
+		if (too)
+			sg_miter_skip(&mo, too);
+		miter_err = sg_miter_next(&mo);
+		if (!miter_err || !mo.addr) {
+			dev_err_ratelimited(ss->dev, "ERROR: sg_miter return null\n");
+			err = -EINVAL;
+			goto release_ss;
+		}
 		/* todo in 4bytes word */
 		todo = min(tx_cnt, oleft / 4);
 		todo = min_t(size_t, todo, (mo.length - oo) / 4);
+
 		if (todo) {
 			readsl(ss->base + SS_TXFIFO, mo.addr + oo, todo);
 			oleft -= todo * 4;
 			oo += todo * 4;
 			if (oo == mo.length) {
-				sg_miter_next(&mo);
+				too += mo.length;
 				oo = 0;
 			}
 		} else {
@@ -352,12 +373,14 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
 				obo += todo;
 				oo += todo;
 				if (oo == mo.length) {
+					too += mo.length;
 					sg_miter_next(&mo);
 					oo = 0;
 				}
 			} while (obo < obl);
 			/* bufo must be fully used here */
 		}
+		sg_miter_stop(&mo);
 	}
 	if (areq->iv) {
 		if (mode & SS_DECRYPTION) {
@@ -370,8 +393,6 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
 	}
 
 release_ss:
-	sg_miter_stop(&mo);
-	sg_miter_stop(&mi);
 	writel(0, ss->base + SS_CTL);
 	spin_unlock_irqrestore(&ss->slock, flags);


  reply	other threads:[~2020-12-07 12:18 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20201201130102.GA23461@Red>
     [not found] ` <87ft4phcyx.fsf@nanos.tec.linutronix.de>
     [not found]   ` <20201201135252.GA9584@Red>
     [not found]     ` <87y2ihfw6z.fsf@nanos.tec.linutronix.de>
     [not found]       ` <20201201144529.GA6786@Red>
     [not found]         ` <87v9dlfthf.fsf@nanos.tec.linutronix.de>
     [not found]           ` <20201202195501.GA29296@Red>
     [not found]             ` <877dpzexfr.fsf@nanos.tec.linutronix.de>
     [not found]               ` <20201203173846.GA16207@Red>
2020-12-03 23:34                 ` crypto: sun4i-ss: error with kmap Thomas Gleixner
2020-12-04 13:26                   ` Corentin Labbe
2020-12-04 15:08                     ` Thomas Gleixner
2020-12-04 19:27                       ` Corentin Labbe
2020-12-04 20:58                         ` Thomas Gleixner
2020-12-05 18:43                           ` Corentin Labbe
2020-12-05 19:48                             ` Thomas Gleixner
2020-12-05 20:16                               ` Julia Lawall
2020-12-06 21:40                               ` Corentin Labbe
2020-12-07  0:15                                 ` Thomas Gleixner
2020-12-07 12:18                                   ` Corentin Labbe [this message]
2020-12-07 15:53                                     ` Thomas Gleixner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201207121820.GB8458@Red \
    --to=clabbe.montjoie@gmail.com \
    --cc=akpm@linuxfoundation.org \
    --cc=axboe@kernel.dk \
    --cc=herbert@gondor.apana.org.au \
    --cc=julia.lawall@lip6.fr \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mripard@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=wens@csie.org \
    --cc=willy@infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).