2015-12-22 12:27:44

by Andre Przywara

[permalink] [raw]
Subject: [RFC PATCH 2/5] crypto: sunxi-ss: fix min3() call to match types

The min3() macro expects all arguments to be of the same type (or
size at least). While two arguments are ints or u32s, one is size_t,
which does not match on 64-bit architectures.
Cast the size_t to u32 to make min3() happy. In this context here the
length should never exceed 32 bits anyway.

Signed-off-by: Andre Przywara <[email protected]>
---
drivers/crypto/sunxi-ss/sun4i-ss-cipher.c | 12 ++++++------
drivers/crypto/sunxi-ss/sun4i-ss-hash.c | 8 ++++----
2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c b/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c
index a19ee12..b3bc7bd 100644
--- a/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c
+++ b/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c
@@ -79,7 +79,7 @@ static int sun4i_ss_opti_poll(struct ablkcipher_request *areq)
oi = 0;
oo = 0;
do {
- todo = min3(rx_cnt, ileft, (mi.length - oi) / 4);
+ todo = min3(rx_cnt, ileft, (u32)(mi.length - oi) / 4);
if (todo > 0) {
ileft -= todo;
writesl(ss->base + SS_RXFIFO, mi.addr + oi, todo);
@@ -94,7 +94,7 @@ static int sun4i_ss_opti_poll(struct ablkcipher_request *areq)
rx_cnt = SS_RXFIFO_SPACES(spaces);
tx_cnt = SS_TXFIFO_SPACES(spaces);

- todo = min3(tx_cnt, oleft, (mo.length - oo) / 4);
+ todo = min3(tx_cnt, oleft, (u32)(mo.length - oo) / 4);
if (todo > 0) {
oleft -= todo;
readsl(ss->base + SS_TXFIFO, mo.addr + oo, todo);
@@ -216,7 +216,7 @@ static int sun4i_ss_cipher_poll(struct ablkcipher_request *areq)
* todo is the number of consecutive 4byte word that we
* can read from current SG
*/
- todo = min3(rx_cnt, ileft / 4, (mi.length - oi) / 4);
+ todo = min3(rx_cnt, ileft / 4, (u32)(mi.length - oi) / 4);
if (todo > 0 && ob == 0) {
writesl(ss->base + SS_RXFIFO, mi.addr + oi,
todo);
@@ -231,7 +231,7 @@ static int sun4i_ss_cipher_poll(struct ablkcipher_request *areq)
* pass, so it is why we min() with rx_cnt
*/
todo = min3(rx_cnt * 4 - ob, ileft,
- mi.length - oi);
+ (u32)mi.length - oi);
memcpy(buf + ob, mi.addr + oi, todo);
ileft -= todo;
oi += todo;
@@ -260,7 +260,7 @@ static int sun4i_ss_cipher_poll(struct ablkcipher_request *areq)
if (tx_cnt == 0)
continue;
/* todo in 4bytes word */
- todo = min3(tx_cnt, oleft / 4, (mo.length - oo) / 4);
+ todo = min3(tx_cnt, oleft / 4, (u32)(mo.length - oo) / 4);
if (todo > 0) {
readsl(ss->base + SS_TXFIFO, mo.addr + oo, todo);
oleft -= todo * 4;
@@ -284,7 +284,7 @@ static int sun4i_ss_cipher_poll(struct ablkcipher_request *areq)
* no more than remaining buffer
* no need to test against oleft
*/
- todo = min(mo.length - oo, obl - obo);
+ todo = min((u32)mo.length - oo, obl - obo);
memcpy(mo.addr + oo, bufo + obo, todo);
oleft -= todo;
obo += todo;
diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-hash.c b/drivers/crypto/sunxi-ss/sun4i-ss-hash.c
index ff80314..cd29009 100644
--- a/drivers/crypto/sunxi-ss/sun4i-ss-hash.c
+++ b/drivers/crypto/sunxi-ss/sun4i-ss-hash.c
@@ -245,7 +245,7 @@ int sun4i_hash_update(struct ahash_request *areq)
*/
while (op->len < 64 && i < end) {
/* how many bytes we can read from current SG */
- in_r = min3(mi.length - in_i, end - i,
+ in_r = min3((u32)mi.length - in_i, end - i,
64 - op->len);
memcpy(op->buf + op->len, mi.addr + in_i, in_r);
op->len += in_r;
@@ -266,8 +266,8 @@ int sun4i_hash_update(struct ahash_request *areq)
}
if (mi.length - in_i > 3 && i < end) {
/* how many bytes we can read from current SG */
- in_r = min3(mi.length - in_i, areq->nbytes - i,
- ((mi.length - in_i) / 4) * 4);
+ in_r = min3((u32)mi.length - in_i, areq->nbytes - i,
+ ((u32)(mi.length - in_i) / 4) * 4);
/* how many bytes we can write in the device*/
todo = min3((u32)(end - i) / 4, rx_cnt, (u32)in_r / 4);
writesl(ss->base + SS_RXFIFO, mi.addr + in_i, todo);
@@ -289,7 +289,7 @@ int sun4i_hash_update(struct ahash_request *areq)
if ((areq->nbytes - i) < 64) {
while (i < areq->nbytes && in_i < mi.length && op->len < 64) {
/* how many bytes we can read from current SG */
- in_r = min3(mi.length - in_i, areq->nbytes - i,
+ in_r = min3((u32)mi.length - in_i, areq->nbytes - i,
64 - op->len);
memcpy(op->buf + op->len, mi.addr + in_i, in_r);
op->len += in_r;
--
2.5.1


2015-12-22 22:06:58

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [RFC PATCH 2/5] crypto: sunxi-ss: fix min3() call to match types

On Tuesday 22 December 2015, Andre Przywara wrote:
> The min3() macro expects all arguments to be of the same type (or
> size at least). While two arguments are ints or u32s, one is size_t,
> which does not match on 64-bit architectures.
> Cast the size_t to u32 to make min3() happy. In this context here the
> length should never exceed 32 bits anyway.
>
> Signed-off-by: Andre Przywara <[email protected]>

Looks correct, but a bit ugly. Could we avoid the casts by using
temporary variables to keep the size_t based data?

Arnd

2015-12-23 00:07:41

by Andre Przywara

[permalink] [raw]
Subject: Re: [RFC PATCH 2/5] crypto: sunxi-ss: fix min3() call to match types

Hi Arnd,
On 12/22/15 22:06, Arnd Bergmann wrote:
> On Tuesday 22 December 2015, Andre Przywara wrote:
>> The min3() macro expects all arguments to be of the same type (or
>> size at least). While two arguments are ints or u32s, one is size_t,
>> which does not match on 64-bit architectures.
>> Cast the size_t to u32 to make min3() happy. In this context here the
>> length should never exceed 32 bits anyway.
>>
>> Signed-off-by: Andre Przywara <[email protected]>
>
> Looks correct, but a bit ugly. Could we avoid the casts by using
> temporary variables to keep the size_t based data?

I guess this gets even uglier, but I found a better solution by
promoting the other involved variables to size_t in this function. This
works nicely for most of the cases, I just need two size_t casts now.
Will send an updated version soon.

Cheers,
Andre.

2016-01-04 14:20:17

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [RFC PATCH 2/5] crypto: sunxi-ss: fix min3() call to match types

On Tue, Dec 22, 2015 at 12:27:44PM +0000, Andre Przywara wrote:
> The min3() macro expects all arguments to be of the same type (or
> size at least). While two arguments are ints or u32s, one is size_t,
> which does not match on 64-bit architectures.
> Cast the size_t to u32 to make min3() happy. In this context here the
> length should never exceed 32 bits anyway.
>
> Signed-off-by: Andre Przywara <[email protected]>
> ---
> drivers/crypto/sunxi-ss/sun4i-ss-cipher.c | 12 ++++++------
> drivers/crypto/sunxi-ss/sun4i-ss-hash.c | 8 ++++----
> 2 files changed, 10 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c b/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c
> index a19ee12..b3bc7bd 100644
> --- a/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c
> +++ b/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c
> @@ -79,7 +79,7 @@ static int sun4i_ss_opti_poll(struct ablkcipher_request *areq)
> oi = 0;
> oo = 0;
> do {
> - todo = min3(rx_cnt, ileft, (mi.length - oi) / 4);
> + todo = min3(rx_cnt, ileft, (u32)(mi.length - oi) / 4);

For this case the min function has a min_t variant to specify the
argument. What about introducing min3_t?

BTW, I don't understand why min3(x, y, z) isn't just defined as

#define min3(x, y, z) min(min(x, y), z)

but instead as:

#define min3(x, y, z) min((typeof(x))min(x, y), z)

. I thought min(x, y) has the same type as x anyhow?

Best regards
Uwe


--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |