[RFC][PATCH] Make cryptoapi non-optional?

2 views
Skip to first unread message

Matt Mackall

unread,
Aug 9, 2003, 3:50:07 AM8/9/03
to
The attached (lightly tested) patch gets rid of the SHA in the
/dev/random code and replaces it with cryptoapi, leaving us with just
one SHA implementation. It also updates syncookies. This code is
already at about 125% of baseline throughput, and can probably reach
250% with some tweaking of cryptoapi's redundant padding (in case
anyone else cares about being able to get 120Mb/s of cryptographically
strong random data).

The potentially controversial part is that the random driver is
currently non-optional and this patch would make cryptoapi
non-optional as well. I plan to cryptoapi-ify the outstanding
MD5 instance as well.

diff -urN -X dontdiff orig/drivers/char/random.c work/drivers/char/random.c
--- orig/drivers/char/random.c 2003-08-08 11:14:15.000000000 -0500
+++ work/drivers/char/random.c 2003-08-08 16:40:30.000000000 -0500
@@ -249,11 +249,13 @@
#include <linux/genhd.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
+#include <linux/crypto.h>

#include <asm/processor.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
+#include <asm/scatterlist.h>

/*
* Configuration information
@@ -772,122 +774,6 @@
add_timer_randomness(disk->random, 0x100+MKDEV(disk->major, disk->first_minor));
}

-/******************************************************************
- *
- * Hash function definition
- *
- *******************************************************************/
-
-/*
- * This chunk of code defines a function
- * void SHATransform(__u32 digest[HASH_BUFFER_SIZE + HASH_EXTRA_SIZE],
- * __u32 const data[16])
- *
- * The function hashes the input data to produce a digest in the first
- * HASH_BUFFER_SIZE words of the digest[] array, and uses HASH_EXTRA_SIZE
- * more words for internal purposes. (This buffer is exported so the
- * caller can wipe it once rather than this code doing it each call,
- * and tacking it onto the end of the digest[] array is the quick and
- * dirty way of doing it.)
- *
- * For /dev/random purposes, the length of the data being hashed is
- * fixed in length, so appending a bit count in the usual way is not
- * cryptographically necessary.
- */
-
-#define HASH_BUFFER_SIZE 5
-#define HASH_EXTRA_SIZE 80
-
-/*
- * SHA transform algorithm, taken from code written by Peter Gutmann,
- * and placed in the public domain.
- */
-
-/* The SHA f()-functions. */
-
-#define f1(x,y,z) ( z ^ (x & (y^z)) ) /* Rounds 0-19: x ? y : z */
-#define f2(x,y,z) (x ^ y ^ z) /* Rounds 20-39: XOR */
-#define f3(x,y,z) ( (x & y) + (z & (x ^ y)) ) /* Rounds 40-59: majority */
-#define f4(x,y,z) (x ^ y ^ z) /* Rounds 60-79: XOR */
-
-/* The SHA Mysterious Constants */
-
-#define K1 0x5A827999L /* Rounds 0-19: sqrt(2) * 2^30 */
-#define K2 0x6ED9EBA1L /* Rounds 20-39: sqrt(3) * 2^30 */
-#define K3 0x8F1BBCDCL /* Rounds 40-59: sqrt(5) * 2^30 */
-#define K4 0xCA62C1D6L /* Rounds 60-79: sqrt(10) * 2^30 */
-
-#define ROTL(n,X) ( ( ( X ) << n ) | ( ( X ) >> ( 32 - n ) ) )
-
-#define subRound(a, b, c, d, e, f, k, data) \
- ( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) )
-
-
-static void SHATransform(__u32 digest[85], __u32 const data[16])
-{
- __u32 A, B, C, D, E; /* Local vars */
- __u32 TEMP;
- int i;
-#define W (digest + HASH_BUFFER_SIZE) /* Expanded data array */
-
- /*
- * Do the preliminary expansion of 16 to 80 words. Doing it
- * out-of-line line like this is faster than doing it in-line on
- * register-starved machines like the x86, and not really any
- * slower on real processors.
- */
- memcpy(W, data, 16*sizeof(__u32));
- for (i = 0; i < 64; i++) {
- TEMP = W[i] ^ W[i+2] ^ W[i+8] ^ W[i+13];
- W[i+16] = ROTL(1, TEMP);
- }
-
- /* Set up first buffer and local data buffer */
- A = digest[ 0 ];
- B = digest[ 1 ];
- C = digest[ 2 ];
- D = digest[ 3 ];
- E = digest[ 4 ];
-
- /* Heavy mangling, in 4 sub-rounds of 20 iterations each. */
- for (i = 0; i < 80; i++) {
- if (i < 40) {
- if (i < 20)
- TEMP = f1(B, C, D) + K1;
- else
- TEMP = f2(B, C, D) + K2;
- } else {
- if (i < 60)
- TEMP = f3(B, C, D) + K3;
- else
- TEMP = f4(B, C, D) + K4;
- }
- TEMP += ROTL(5, A) + E + W[i];
- E = D; D = C; C = ROTL(30, B); B = A; A = TEMP;
- }
-
- /* Build message digest */
- digest[ 0 ] += A;
- digest[ 1 ] += B;
- digest[ 2 ] += C;
- digest[ 3 ] += D;
- digest[ 4 ] += E;
-
- /* W is wiped by the caller */
-#undef W
-}
-
-#undef ROTL
-#undef f1
-#undef f2
-#undef f3
-#undef f4
-#undef K1
-#undef K2
-#undef K3
-#undef K4
-#undef subRound
-
/*********************************************************************
*
* Entropy extraction routines
@@ -896,8 +782,6 @@

#define EXTRACT_ENTROPY_USER 1
#define EXTRACT_ENTROPY_LIMIT 2
-#define TMP_BUF_SIZE (HASH_BUFFER_SIZE + HASH_EXTRA_SIZE)
-#define SEC_XFER_SIZE (TMP_BUF_SIZE*4)

static ssize_t extract_entropy(struct entropy_store *r, void * buf,
size_t nbytes, int flags);
@@ -909,7 +793,7 @@
*/
static void reseed_pool(struct entropy_store *r, int margin, int wanted)
{
- __u32 tmp[TMP_BUF_SIZE];
+ __u32 tmp[32]; /* 256 bits */
int bytes;

DEBUG_ENT("reseed %s wants %d bits (margin %d)\n",
@@ -944,14 +828,11 @@
static ssize_t extract_entropy(struct entropy_store *r, void * buf,
size_t nbytes, int flags)
{
- ssize_t ret, i;
- __u32 tmp[TMP_BUF_SIZE];
- __u32 x;
+ ssize_t ret, i, x;
unsigned long cpuflags;
-
- /* Redundant, but just in case... */
- if (r->entropy_count > r->poolinfo->POOLBITS)
- r->entropy_count = r->poolinfo->POOLBITS;
+ struct crypto_tfm *tfm;
+ struct scatterlist sg[1];
+ __u32 hash[5]; /* 160 bits */

/* Hold lock while accounting */
spin_lock_irqsave(&r->lock, cpuflags);
@@ -975,6 +856,9 @@
spin_unlock_irqrestore(&r->lock, cpuflags);

ret = 0;
+
+ tfm = crypto_alloc_tfm("sha1", 0);
+
while (nbytes) {
/*
* Check if we need to break out or reschedule....
@@ -987,19 +871,10 @@
}

DEBUG_ENT("extract sleep (%d bytes left)\n", nbytes);
-
schedule();
-
DEBUG_ENT("extract wake\n");
}

- /* Hash the pool to get the output */
- tmp[0] = 0x67452301;
- tmp[1] = 0xefcdab89;
- tmp[2] = 0x98badcfe;
- tmp[3] = 0x10325476;
- tmp[4] = 0xc3d2e1f0;
-
/*
* As we hash the pool, we mix intermediate values of
* the hash back into the pool. This eliminates
@@ -1008,40 +883,40 @@
* attempts to find previous ouputs), unless the hash
* function can be inverted.
*/
+
for (i = 0, x = 0; i < r->poolinfo->poolwords; i += 16, x+=2) {
- SHATransform(tmp, r->pool+i);
- add_entropy_words(r, &tmp[x%HASH_BUFFER_SIZE], 1);
+ sg[0].page = virt_to_page(r->pool+i);
+ sg[0].offset = ((long)(r->pool+i) & ~PAGE_MASK);
+ sg[0].length = 64;
+ crypto_digest_digest(tfm, sg, 1, (char *)hash);
+ add_entropy_words(r, &hash[x%20], 1);
}

/*
* In case the hash function has some recognizable
* output pattern, we fold it in half.
*/
- for (i = 0; i < HASH_BUFFER_SIZE/2; i++)
- tmp[i] ^= tmp[i + (HASH_BUFFER_SIZE+1)/2];
-#if HASH_BUFFER_SIZE & 1 /* There's a middle word to deal with */
- x = tmp[HASH_BUFFER_SIZE/2];
- x ^= (x >> 16); /* Fold it in half */
- ((__u16 *)tmp)[HASH_BUFFER_SIZE-1] = (__u16)x;
-#endif
+ hash[0] ^= hash[3];
+ hash[1] ^= hash[4];

/* Copy data to destination buffer */
- i = min(nbytes, HASH_BUFFER_SIZE*sizeof(__u32)/2);
+ i = min(nbytes, sizeof(hash)/2);
if (flags & EXTRACT_ENTROPY_USER) {
- i -= copy_to_user(buf, (__u8 const *)tmp, i);
+ i -= copy_to_user(buf, (__u8 const *)hash, i);
if (!i) {
ret = -EFAULT;
break;
}
} else
- memcpy(buf, (__u8 const *)tmp, i);
+ memcpy(buf, (__u8 const *)hash, i);
nbytes -= i;
buf += i;
ret += i;
}

/* Wipe data just returned from memory */
- memset(tmp, 0, sizeof(tmp));
+ memset(hash, 0, sizeof(hash));
+ crypto_free_tfm(tfm);

return ret;
}
@@ -1160,15 +1035,10 @@
static ssize_t
random_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
{
- ssize_t n, retval = 0, count = 0;
+ ssize_t n, retval = 0, count = 0;

- if (nbytes == 0)
- return 0;
-
while (nbytes > 0) {
- n = nbytes;
- if (n > SEC_XFER_SIZE)
- n = SEC_XFER_SIZE;
+ n = min_t(size_t, nbytes, BLOCKING_POOL_SIZE/8);

/* We can take all the entropy in the input pool */
reseed_pool(blocking_pool, 0, n);
@@ -1846,13 +1716,16 @@
#define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1)

static int syncookie_init;
-static __u32 syncookie_secret[2][16-3+HASH_BUFFER_SIZE];
+static __u32 syncookie_secret[2][16-3];

__u32 secure_tcp_syn_cookie(__u32 saddr, __u32 daddr, __u16 sport,
__u16 dport, __u32 sseq, __u32 count, __u32 data)
{
- __u32 tmp[16 + HASH_BUFFER_SIZE + HASH_EXTRA_SIZE];
- __u32 seq;
+ __u32 tmp[16]; /* 512 bits */
+ __u32 hash[5]; /* 160 bits */
+ __u32 seq;
+ struct crypto_tfm *tfm;
+ struct scatterlist sg[1];

/*
* Pick two random secrets the first time we need a cookie.
@@ -1873,22 +1746,27 @@
* MSS into the second hash value.
*/

- memcpy(tmp+3, syncookie_secret[0], sizeof(syncookie_secret[0]));
+ sg[0].page = virt_to_page(tmp);
+ sg[0].offset = ((long) tmp & ~PAGE_MASK);
+ sg[0].length = sizeof(tmp);
+
tmp[0]=saddr;
tmp[1]=daddr;
tmp[2]=(sport << 16) + dport;
- SHATransform(tmp+16, tmp);
- seq = tmp[17] + sseq + (count << COOKIEBITS);
+
+ memcpy(tmp+3, syncookie_secret[0], sizeof(syncookie_secret[0]));
+ tfm = crypto_alloc_tfm("sha1", 0);
+ crypto_digest_digest(tfm, sg, 1, (char *)hash);
+
+ seq = hash[1] + sseq + (count << COOKIEBITS);

memcpy(tmp+3, syncookie_secret[1], sizeof(syncookie_secret[1]));
- tmp[0]=saddr;
- tmp[1]=daddr;
- tmp[2]=(sport << 16) + dport;
tmp[3] = count; /* minute counter */
- SHATransform(tmp+16, tmp);
+ crypto_digest_digest(tfm, sg, 1, (char *)hash);
+ crypto_free_tfm(tfm);

/* Add in the second hash and the data */
- return seq + ((tmp[17] + data) & COOKIEMASK);
+ return seq + ((hash[1] + data) & COOKIEMASK);
}

/*
@@ -1903,19 +1781,29 @@
__u32 check_tcp_syn_cookie(__u32 cookie, __u32 saddr, __u32 daddr, __u16 sport,
__u16 dport, __u32 sseq, __u32 count, __u32 maxdiff)
{
- __u32 tmp[16 + HASH_BUFFER_SIZE + HASH_EXTRA_SIZE];
- __u32 diff;
+ __u32 tmp[16]; /* 512 bits */
+ __u32 hash[5]; /* 160 bits */
+ __u32 diff;
+ struct crypto_tfm *tfm;
+ struct scatterlist sg[1];

if (syncookie_init == 0)
return (__u32)-1; /* Well, duh! */

- /* Strip away the layers from the cookie */
- memcpy(tmp+3, syncookie_secret[0], sizeof(syncookie_secret[0]));
+ sg[0].page = virt_to_page(tmp);
+ sg[0].offset = ((long) tmp & ~PAGE_MASK);
+ sg[0].length = sizeof(tmp);
+
tmp[0]=saddr;
tmp[1]=daddr;
tmp[2]=(sport << 16) + dport;
- SHATransform(tmp+16, tmp);
- cookie -= tmp[17] + sseq;
+
+ /* Strip away the layers from the cookie */
+ memcpy(tmp+3, syncookie_secret[0], sizeof(syncookie_secret[0]));
+ tfm = crypto_alloc_tfm("sha1", 0);
+ crypto_digest_digest(tfm, sg, 1, (char *)hash);
+
+ cookie -= hash[1] + sseq;
/* Cookie is now reduced to (count * 2^24) ^ (hash % 2^24) */

diff = (count - (cookie >> COOKIEBITS)) & ((__u32)-1 >> COOKIEBITS);
@@ -1923,13 +1811,11 @@
return (__u32)-1;

memcpy(tmp+3, syncookie_secret[1], sizeof(syncookie_secret[1]));
- tmp[0] = saddr;
- tmp[1] = daddr;
- tmp[2] = (sport << 16) + dport;
tmp[3] = count - diff; /* minute counter */
- SHATransform(tmp+16, tmp);
+ crypto_digest_digest(tfm, sg, 1, (char *)hash);
+ crypto_free_tfm(tfm);

- return (cookie - tmp[17]) & COOKIEMASK; /* Leaving the data behind */
+ return (cookie - hash[1]) & COOKIEMASK; /* Leaving the data behind */
}
#endif

--
Matt Mackall : http://www.selenic.com : of or relating to the moon
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majo...@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

David S. Miller

unread,
Aug 9, 2003, 4:20:05 AM8/9/03
to
On Sat, 9 Aug 2003 02:44:59 -0500
Matt Mackall <m...@selenic.com> wrote:

> The attached (lightly tested) patch gets rid of the SHA in the
> /dev/random code and replaces it with cryptoapi, leaving us with just
> one SHA implementation.

...


> __u32 secure_tcp_syn_cookie(__u32 saddr, __u32 daddr, __u16 sport,
> __u16 dport, __u32 sseq, __u32 count, __u32 data)

...


> + tfm = crypto_alloc_tfm("sha1", 0);

secure_tcp_syn_cookie() is called from software interrupt
context, therefore it may not sleep.

So you cannot call crypto_alloc_tfm() here, which can sleep.

Not to mention that calling crypto_alloc_tfm() for every TCP
connection creation is absurdly expensive.

Same thing in check_tcp_syn_cookie().

Also, same problem exists with extract_entropy() which also must be
callable from software interrupt context, and thus the
crypto_alloc_tfm() alloc calls you added there are illegal too.

This patch needs tons of work.

Matt Mackall

unread,
Aug 9, 2003, 10:20:04 AM8/9/03
to
On Sat, Aug 09, 2003 at 01:04:18AM -0700, David S. Miller wrote:
> On Sat, 9 Aug 2003 02:44:59 -0500
> Matt Mackall <m...@selenic.com> wrote:
>
> > The attached (lightly tested) patch gets rid of the SHA in the
> > /dev/random code and replaces it with cryptoapi, leaving us with just
> > one SHA implementation.
> ...
> > __u32 secure_tcp_syn_cookie(__u32 saddr, __u32 daddr, __u16 sport,
> > __u16 dport, __u32 sseq, __u32 count, __u32 data)
> ...
> > + tfm = crypto_alloc_tfm("sha1", 0);
>

> This patch needs tons of work.

Yes, it's completely bogus. It also needs tons of error-checking, etc.
All of which is a big waste of time if the answer to "is making
cryptoapi mandatory ok?" is no. So before embarking on the hard part,
I thought I'd ask the hard question.

--
Matt Mackall : http://www.selenic.com : of or relating to the moon

Matt Mackall

unread,
Aug 9, 2003, 10:40:09 AM8/9/03
to
On Sat, Aug 09, 2003 at 02:44:59AM -0500, Matt Mackall wrote:
> The attached (lightly tested) patch gets rid of the SHA in the
> /dev/random code and replaces it with cryptoapi, leaving us with just
> one SHA implementation. It also updates syncookies. This code is
> already at about 125% of baseline throughput, and can probably reach
> 250% with some tweaking of cryptoapi's redundant padding (in case
> anyone else cares about being able to get 120Mb/s of cryptographically
> strong random data).
>
> The potentially controversial part is that the random driver is
> currently non-optional and this patch would make cryptoapi
> non-optional as well. I plan to cryptoapi-ify the outstanding
> MD5 instance as well.

Some details I left out at 3am:

- this code is just a proof of concept
- the random number generator is non-optional because it's used
various things from filesystems to networking
- the cryptoapi layer is itself quite thin (the .o is about 2.8k
stripped on my box)

An alternative approach is to subvert cryptoapi by pulling the core
transform out of the SHA1 module and putting it in the core with hooks
so /dev/random can get at it directly. Downsides are subverting the
api and losing pluggability. Upsides are avoiding api overhead and
potential sleeping.

Jamie Lokier

unread,
Aug 9, 2003, 1:20:10 PM8/9/03
to
Matt Mackall wrote:
> This code is already at about 125% of baseline throughput, and can
> probably reach 250% with some tweaking of cryptoapi's redundant
> padding (in case anyone else cares about being able to get 120Mb/s
> of cryptographically strong random data).

Why would the cryptoapi version be faster, I wondered? So I had a look.
No conclusions, just observations.

- random.c defines a constant, SHA_CODE_SIZE. This selects between
4 implementations, from smaller to (presumably) faster by
progressively unrolling more and more.

This is set to SHA_CODE_SIZE == 0, for smallest code.

In crypto/sha1.c, the code is roughly equivalent to SHA_CODE_SIZE == 3,
random.c's _largest_ implementation.

So you seem to be replacing a small version with a large version,
albeit faster.

- One of the optimisations in crypto/sha1.c is:

/* blk0() and blk() perform the initial expand. */
/* I got the idea of expanding during the round function from SSLeay */

Yet, random.c has the opposite:

/*


* Do the preliminary expansion of 16 to 80 words. Doing it

* out-of-line line this is faster than doing it in-line on


* register-starved machines like the x86, and not really any

* slower on real processors.

*/

I wonder if the random.c method is faster on x86?

- sha1_transform() in crypto/sha1.c ends with this misleading
comment. Was the author trying to prevent data leakage? If so,
he failed:

/* Wipe variables */
a = b = c = d = e = 0;
memset (block32, 0x00, sizeof block32);

The second line will definitely be optimised away. The third
could be, although GCC doesn't.

Enjoy,
-- Jamie

Matt Mackall

unread,
Aug 9, 2003, 1:40:10 PM8/9/03
to
On Sat, Aug 09, 2003 at 06:13:18PM +0100, Jamie Lokier wrote:
> Matt Mackall wrote:
> > This code is already at about 125% of baseline throughput, and can
> > probably reach 250% with some tweaking of cryptoapi's redundant
> > padding (in case anyone else cares about being able to get 120Mb/s
> > of cryptographically strong random data).
>
> Why would the cryptoapi version be faster, I wondered? So I had a look.
> No conclusions, just observations.
>
> - random.c defines a constant, SHA_CODE_SIZE. This selects between
> 4 implementations, from smaller to (presumably) faster by
> progressively unrolling more and more.
>
> This is set to SHA_CODE_SIZE == 0, for smallest code.
>
> In crypto/sha1.c, the code is roughly equivalent to SHA_CODE_SIZE == 3,
> random.c's _largest_ implementation.
>
> So you seem to be replacing a small version with a large version,
> albeit faster.

Yes. I've got another patch to include a non-unrolled version of SHA
in cryptolib but that depends on some config magic I haven't thought
out. Another thing I failed to mention at 3am is that most of the
speed increase actually comes from the following patch which wasn't in
baseline and isn't cryptoapi-specific. So I expect the cryptoapi
version is about 30% faster once you amortize the initialization
stuff.

>>>>
Remove folding step and double throughput.

If there was a recognizable output pattern, simply folding would make
things worse. To see why, assume bits x and y are correlated, but are
othewise random. Then x^y has a bias toward zero, meaning less entropy
than just x alone.

Best case, this is the moral equivalent of running every bit through
SHA four times rather than twice. Twice should be more than enough.

diff -urN -X dontdiff orig/drivers/char/random.c work/drivers/char/random.c

--- orig/drivers/char/random.c 2003-08-09 10:25:46.000000000 -0500
+++ work/drivers/char/random.c 2003-08-09 10:31:27.000000000 -0500
@@ -1013,20 +1013,8 @@


add_entropy_words(r, &tmp[x%HASH_BUFFER_SIZE], 1);
}

- /*
- * In case the hash function has some recognizable
- * output pattern, we fold it in half.
- */


- for (i = 0; i < HASH_BUFFER_SIZE/2; i++)
- tmp[i] ^= tmp[i + (HASH_BUFFER_SIZE+1)/2];
-#if HASH_BUFFER_SIZE & 1 /* There's a middle word to deal with */
- x = tmp[HASH_BUFFER_SIZE/2];
- x ^= (x >> 16); /* Fold it in half */
- ((__u16 *)tmp)[HASH_BUFFER_SIZE-1] = (__u16)x;
-#endif

-

/* Copy data to destination buffer */
- i = min(nbytes, HASH_BUFFER_SIZE*sizeof(__u32)/2);

+ i = min(nbytes, HASH_BUFFER_SIZE*sizeof(__u32));
if (flags & EXTRACT_ENTROPY_USER) {


i -= copy_to_user(buf, (__u8 const *)tmp, i);

if (!i) {

>>>>>

> - One of the optimisations in crypto/sha1.c is:
>
> /* blk0() and blk() perform the initial expand. */
> /* I got the idea of expanding during the round function from SSLeay */
>
> Yet, random.c has the opposite:
>
> /*
> * Do the preliminary expansion of 16 to 80 words. Doing it
> * out-of-line line this is faster than doing it in-line on
> * register-starved machines like the x86, and not really any
> * slower on real processors.
> */
>
> I wonder if the random.c method is faster on x86?

They're probably equal on modern machines. The random code is from 486 days.

> - sha1_transform() in crypto/sha1.c ends with this misleading
> comment. Was the author trying to prevent data leakage? If so,
> he failed:
>
> /* Wipe variables */
> a = b = c = d = e = 0;
> memset (block32, 0x00, sizeof block32);
>
> The second line will definitely be optimised away. The third
> could be, although GCC doesn't.

Preventing data leakage is the intent, though I'm not sure its worth
the trouble. If your attacker can leverage this sort of data leakage,
you probably have more important stuff to worry about.

--
Matt Mackall : http://www.selenic.com : of or relating to the moon

David S. Miller

unread,
Aug 9, 2003, 1:50:10 PM8/9/03
to
On Sat, 9 Aug 2003 09:05:42 -0500
Matt Mackall <m...@selenic.com> wrote:

> All of which is a big waste of time if the answer to "is making
> cryptoapi mandatory ok?" is no. So before embarking on the hard part,
> I thought I'd ask the hard question.

I'm personally OK with it, and in fact I talked about this with James
(converting random.c over to the crypto API and the implications)
early on while we were first working on the crypto kernel bits.

But I fear some embedded folks might bark. Especially if the
resulting code size is significantly larger.

We could make it a config option CONFIG_RANDOM_CRYPTOAPI.

All of this analysis nearly requires a working implementation so
someone can do a code-size and performance comparison between
the two cases. I know this is what you're trying to avoid, having
to code up what might be just thrown away :(

Matt Mackall

unread,
Aug 9, 2003, 4:00:11 PM8/9/03
to
On Sat, Aug 09, 2003 at 10:39:10AM -0700, David S. Miller wrote:
> On Sat, 9 Aug 2003 09:05:42 -0500
> Matt Mackall <m...@selenic.com> wrote:
>
> > All of which is a big waste of time if the answer to "is making
> > cryptoapi mandatory ok?" is no. So before embarking on the hard part,
> > I thought I'd ask the hard question.
>
> I'm personally OK with it, and in fact I talked about this with James
> (converting random.c over to the crypto API and the implications)
> early on while we were first working on the crypto kernel bits.
>
> But I fear some embedded folks might bark. Especially if the
> resulting code size is significantly larger.

An alternate approach is:

- pull the minimum parts of SHA (and perhaps MD5) out of their
respective cryptoapi modules into the core
- call that code directly from random, bypassing cryptoapi (and
avoiding all the dynamic allocation and potential sleeping stuff)

Combined with a patch that does non-unrolled SHA, this should be about
the same as the present code.

> We could make it a config option CONFIG_RANDOM_CRYPTOAPI.

As the primary benefit here is elimination of duplicate code, I think
that's a non-starter.



> All of this analysis nearly requires a working implementation so
> someone can do a code-size and performance comparison between
> the two cases. I know this is what you're trying to avoid, having
> to code up what might be just thrown away :(

Ok, can I export some more cryptoapi primitives?

__crypto_lookup_alg(const char *name);
__crypto_alg_tfm_size(const char *name);
__crypto_setup_tfm(struct crypto_alg *alg, char *buf, int size, int flags);
__crypto_exit_ops(...)
__crypto_alg_put(...);

This would let me do alg lookup in my init and avoid the dynamic
allocation sleeping and performance hits.

Also, I posted to cryptoapi-devel that I need a way to disable the
unconditional padding on the hash functions.

--
Matt Mackall : http://www.selenic.com : of or relating to the moon

David S. Miller

unread,
Aug 9, 2003, 4:30:11 PM8/9/03
to
On Sat, 9 Aug 2003 14:46:27 -0500
Matt Mackall <m...@selenic.com> wrote:

> On Sat, Aug 09, 2003 at 10:39:10AM -0700, David S. Miller wrote:
> > All of this analysis nearly requires a working implementation so
> > someone can do a code-size and performance comparison between
> > the two cases. I know this is what you're trying to avoid, having
> > to code up what might be just thrown away :(
>
> Ok, can I export some more cryptoapi primitives?
>
> __crypto_lookup_alg(const char *name);
> __crypto_alg_tfm_size(const char *name);
> __crypto_setup_tfm(struct crypto_alg *alg, char *buf, int size, int flags);
> __crypto_exit_ops(...)
> __crypto_alg_put(...);

No, this eliminates the whole point of all the abstractions.
Please just use the APIs properly.

> This would let me do alg lookup in my init and avoid the dynamic
> allocation sleeping and performance hits.

How about allocating the tfm(s) (one per cpu on SMP) at module
init time? That's how I would implement this.

Please try to implement something using the existing APIs.

It's not the size of the cryptoapi core that I'm worries about
(that's only like 1K or 2K on 32-bit systems), it's the SHA1/MD*
code which is a bit larger. This might all cancel out once the
SHA1/MD* code is deleted from random.o, and your implementation
will prove/disprove this, and then we can move onto perf analysis.

> Also, I posted to cryptoapi-devel that I need a way to disable the
> unconditional padding on the hash functions.

James, comments?

Robert Love

unread,
Aug 9, 2003, 10:10:07 PM8/9/03
to
On Sat, 2003-08-09 at 07:33, Matt Mackall wrote:

> - the random number generator is non-optional because it's used
> various things from filesystems to networking

What if you kept crypto API optional, made random.c a config option, and
make that depend on the crypto API. Then -- and this is the non-obvious
part -- implement a super lame replacement for get_random_bytes() [what
I assume the various parts of the kernel are using] for when
!CONFIG_RANDOM is not set?

You can do a simple PRNG in <10 lines of C. Have the kernel seed it on
boot with xtime or something else lame.

Robert Love

Matt Mackall

unread,
Aug 9, 2003, 11:20:04 PM8/9/03
to
On Sat, Aug 09, 2003 at 07:07:27PM -0700, Robert Love wrote:
> On Sat, 2003-08-09 at 07:33, Matt Mackall wrote:
>
> > - the random number generator is non-optional because it's used
> > various things from filesystems to networking
>
> What if you kept crypto API optional, made random.c a config option, and
> make that depend on the crypto API. Then -- and this is the non-obvious
> part -- implement a super lame replacement for get_random_bytes() [what
> I assume the various parts of the kernel are using] for when
> !CONFIG_RANDOM is not set?
>
> You can do a simple PRNG in <10 lines of C. Have the kernel seed it on
> boot with xtime or something else lame.

Eek, let's not go there. Most of the users of get_random_bytes()
depend on it being strong enough for cryptographic purposes. And we've
long guaranteed the existence of a cryptographically strong
/dev/urandom. If userspace could no longer rely on it being there,
people would be forced to go back to poorly reinventing it in
userspace - not good. Having random.c be nonoptional is a good note to
embedded folks that they should think long and hard before ripping it
out.

--
Matt Mackall : http://www.selenic.com : of or relating to the moon

Robert Love

unread,
Aug 10, 2003, 12:10:06 AM8/10/03
to
On Sat, 2003-08-09 at 20:49, David S. Miller wrote:

> I definitely agree, removing the integrity of random.c is not
> an option. Even things inside the kernel itself rely upon
> get_random_bytes() for anti-DoS measures.

OK, fair enough. I liked the idea because it let things stay optional,
but also gave us no excuse not to merge Matt's changes.

I would have no problem requiring cryptoapi, but what if it increases in
size? Requiring a large (and definitely oft-used for many people)
feature isn't size, either.

Robert Love

David S. Miller

unread,
Aug 10, 2003, 12:10:04 AM8/10/03
to
On Sat, 9 Aug 2003 22:14:18 -0500
Matt Mackall <m...@selenic.com> wrote:

> On Sat, Aug 09, 2003 at 07:07:27PM -0700, Robert Love wrote:
> > On Sat, 2003-08-09 at 07:33, Matt Mackall wrote:
> > What if you kept crypto API optional, made random.c a config option, and
> > make that depend on the crypto API.

...


> Eek, let's not go there.

I definitely agree, removing the integrity of random.c is not


an option. Even things inside the kernel itself rely upon
get_random_bytes() for anti-DoS measures.

Robert Love

unread,
Aug 10, 2003, 12:10:07 AM8/10/03
to
On Sat, 2003-08-09 at 21:01, Robert Love wrote:

> Requiring a large (and definitely oft-used for many people)
> feature isn't size, either.

Eh, s/size/cool/

Matt Mackall

unread,
Aug 10, 2003, 4:20:06 AM8/10/03
to
On Sat, Aug 09, 2003 at 01:17:15PM -0700, David S. Miller wrote:
> On Sat, 9 Aug 2003 14:46:27 -0500
> Matt Mackall <m...@selenic.com> wrote:
>
> > On Sat, Aug 09, 2003 at 10:39:10AM -0700, David S. Miller wrote:
> > > All of this analysis nearly requires a working implementation so
> > > someone can do a code-size and performance comparison between
> > > the two cases. I know this is what you're trying to avoid, having
> > > to code up what might be just thrown away :(
> >
> > Ok, can I export some more cryptoapi primitives?

[snip]

> How about allocating the tfm(s) (one per cpu on SMP) at module
> init time? That's how I would implement this.

Ok, done.

- percpu tfms
- move random to initcall so that it gets initialized after cryptoapi
- fix resched check in crypto_yield
- appears to work

..though I don't like that this approach ends up having to do the
hashing between get_cpu/put_cpu with preemption disabled while the
original code was fully reentrant.

diff -urN -X dontdiff orig/crypto/internal.h work/crypto/internal.h
--- orig/crypto/internal.h 2003-07-13 22:29:11.000000000 -0500
+++ work/crypto/internal.h 2003-08-10 02:43:41.000000000 -0500
@@ -37,7 +37,7 @@

static inline void crypto_yield(struct crypto_tfm *tfm)
{
- if (!in_softirq())
+ if (!in_atomic())
cond_resched();
}

diff -urN -X dontdiff orig/drivers/char/mem.c work/drivers/char/mem.c
--- orig/drivers/char/mem.c 2003-07-13 22:34:32.000000000 -0500
+++ work/drivers/char/mem.c 2003-08-10 02:11:30.000000000 -0500
@@ -680,7 +680,6 @@
S_IFCHR | devlist[i].mode, devlist[i].name);
}

- rand_initialize();
#if defined (CONFIG_FB)
fbmem_init();
#endif


diff -urN -X dontdiff orig/drivers/char/random.c work/drivers/char/random.c

--- orig/drivers/char/random.c 2003-08-09 22:28:50.000000000 -0500
+++ work/drivers/char/random.c 2003-08-10 02:13:51.000000000 -0500
@@ -249,11 +249,16 @@


#include <linux/genhd.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
+#include <linux/crypto.h>

+#include <linux/cpu.h>
+#include <linux/percpu.h>
+#include <linux/notifier.h>



#include <asm/processor.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
+#include <asm/scatterlist.h>

/*
* Configuration information

@@ -360,7 +365,7 @@
* modulo the generator polymnomial. Now, for random primitive polynomials,
* this is a universal class of hash functions, meaning that the chance
* of a collision is limited by the attacker's knowledge of the generator
- * polynomail, so if it is chosen at random, an attacker can never force
+ * polynomial, so if it is chosen at random, an attacker can never force
* a collision. Here, we use a fixed polynomial, but we *can* assume that
* ###--> it is unknown to the processes generating the input entropy. <-###
* Because of this important property, this is a good, collision-resistant
@@ -374,6 +379,8 @@
static DECLARE_WAIT_QUEUE_HEAD(random_read_wait);
static DECLARE_WAIT_QUEUE_HEAD(random_write_wait);

+static DEFINE_PER_CPU(struct crypto_tfm *, sha_tfm);
+
/*
* Forward procedure declarations
*/
@@ -773,122 +780,6 @@

@@ -897,8 +788,6 @@



#define EXTRACT_ENTROPY_USER 1
#define EXTRACT_ENTROPY_LIMIT 2
-#define TMP_BUF_SIZE (HASH_BUFFER_SIZE + HASH_EXTRA_SIZE)
-#define SEC_XFER_SIZE (TMP_BUF_SIZE*4)

static ssize_t extract_entropy(struct entropy_store *r, void * buf,
size_t nbytes, int flags);

@@ -910,7 +799,7 @@


*/
static void reseed_pool(struct entropy_store *r, int margin, int wanted)
{
- __u32 tmp[TMP_BUF_SIZE];
+ __u32 tmp[32]; /* 256 bits */
int bytes;

DEBUG_ENT("reseed %s wants %d bits (margin %d)\n",

@@ -945,14 +834,11 @@


static ssize_t extract_entropy(struct entropy_store *r, void * buf,
size_t nbytes, int flags)
{
- ssize_t ret, i;
- __u32 tmp[TMP_BUF_SIZE];
- __u32 x;
+ ssize_t ret, i, x;
unsigned long cpuflags;
-
- /* Redundant, but just in case... */
- if (r->entropy_count > r->poolinfo->POOLBITS)
- r->entropy_count = r->poolinfo->POOLBITS;
+ struct crypto_tfm *tfm;
+ struct scatterlist sg[1];
+ __u32 hash[5]; /* 160 bits */

/* Hold lock while accounting */
spin_lock_irqsave(&r->lock, cpuflags);

@@ -976,6 +862,7 @@


spin_unlock_irqrestore(&r->lock, cpuflags);

ret = 0;
+

while (nbytes) {
/*
* Check if we need to break out or reschedule....

@@ -988,19 +875,10 @@


}

DEBUG_ENT("extract sleep (%d bytes left)\n", nbytes);
-
schedule();
-
DEBUG_ENT("extract wake\n");
}

- /* Hash the pool to get the output */
- tmp[0] = 0x67452301;
- tmp[1] = 0xefcdab89;
- tmp[2] = 0x98badcfe;
- tmp[3] = 0x10325476;
- tmp[4] = 0xc3d2e1f0;
-
/*
* As we hash the pool, we mix intermediate values of
* the hash back into the pool. This eliminates

@@ -1009,29 +887,34 @@


* attempts to find previous ouputs), unless the hash
* function can be inverted.
*/
+
for (i = 0, x = 0; i < r->poolinfo->poolwords; i += 16, x+=2) {
- SHATransform(tmp, r->pool+i);
- add_entropy_words(r, &tmp[x%HASH_BUFFER_SIZE], 1);
+ sg[0].page = virt_to_page(r->pool+i);
+ sg[0].offset = ((long)(r->pool+i) & ~PAGE_MASK);
+ sg[0].length = 64;

+ tfm=get_cpu_var(sha_tfm);


+ crypto_digest_digest(tfm, sg, 1, (char *)hash);

+ put_cpu_var(sha_tfm);


+ add_entropy_words(r, &hash[x%20], 1);
}

/* Copy data to destination buffer */

- i = min(nbytes, HASH_BUFFER_SIZE*sizeof(__u32));
+ i = min(nbytes, sizeof(hash));


if (flags & EXTRACT_ENTROPY_USER) {
- i -= copy_to_user(buf, (__u8 const *)tmp, i);
+ i -= copy_to_user(buf, (__u8 const *)hash, i);
if (!i) {
ret = -EFAULT;
break;
}
} else
- memcpy(buf, (__u8 const *)tmp, i);
+ memcpy(buf, (__u8 const *)hash, i);
nbytes -= i;
buf += i;
ret += i;
}

/* Wipe data just returned from memory */
- memset(tmp, 0, sizeof(tmp));

-
+ memset(hash, 0, sizeof(hash));
return ret;
}

@@ -1089,7 +972,25 @@
}
}

-void __init rand_initialize(void)
+static int random_cpu_notify(struct notifier_block *self,
+ unsigned long action, void *hcpu)
+{
+ if (action == CPU_UP_PREPARE)
+ {
+ per_cpu(sha_tfm, (long)hcpu) = crypto_alloc_tfm("sha1", 0);
+
+ printk(KERN_NOTICE "random cpu %ld sha_tfm = %p\n",
+ (long)hcpu, per_cpu(sha_tfm, (long)hcpu));
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block random_nb = {
+ .notifier_call = random_cpu_notify,
+};
+
+static int __init init_random(void)
{
int i;

@@ -1099,10 +1000,14 @@
"nonblocking");

if(!(input_pool && blocking_pool && nonblocking_pool))
- return;
+ return -ENOMEM;

- if(batch_entropy_init(BATCH_ENTROPY_SIZE))
- return;
+ if((i=batch_entropy_init(BATCH_ENTROPY_SIZE)) != 0)
+ return i;
+
+ random_cpu_notify(&random_nb, (unsigned long)CPU_UP_PREPARE,
+ (void *)(long)smp_processor_id());
+ register_cpu_notifier(&random_nb);

init_std_data(input_pool);
sysctl_init_random(input_pool);
@@ -1111,8 +1016,12 @@
irq_timer_state[i] = NULL;
memset(&keyboard_timer_state, 0, sizeof(struct timer_rand_state));
memset(&mouse_timer_state, 0, sizeof(struct timer_rand_state));
+
+ return 0;
}

+__initcall(init_random);
+
void rand_initialize_irq(int irq)
{
struct timer_rand_state *state;
@@ -1149,15 +1058,10 @@


static ssize_t
random_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
{
- ssize_t n, retval = 0, count = 0;
+ ssize_t n, retval = 0, count = 0;

- if (nbytes == 0)
- return 0;
-
while (nbytes > 0) {
- n = nbytes;
- if (n > SEC_XFER_SIZE)
- n = SEC_XFER_SIZE;
+ n = min_t(size_t, nbytes, BLOCKING_POOL_SIZE/8);

/* We can take all the entropy in the input pool */
reseed_pool(blocking_pool, 0, n);

@@ -1835,13 +1739,16 @@


#define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1)

static int syncookie_init;
-static __u32 syncookie_secret[2][16-3+HASH_BUFFER_SIZE];
+static __u32 syncookie_secret[2][16-3];

__u32 secure_tcp_syn_cookie(__u32 saddr, __u32 daddr, __u16 sport,
__u16 dport, __u32 sseq, __u32 count, __u32 data)

{
- __u32 tmp[16 + HASH_BUFFER_SIZE + HASH_EXTRA_SIZE];
- __u32 seq;
+ __u32 tmp[16]; /* 512 bits */
+ __u32 hash[5]; /* 160 bits */
+ __u32 seq;
+ struct crypto_tfm *tfm;
+ struct scatterlist sg[1];

/*
* Pick two random secrets the first time we need a cookie.

@@ -1862,22 +1769,27 @@


* MSS into the second hash value.
*/

- memcpy(tmp+3, syncookie_secret[0], sizeof(syncookie_secret[0]));
+ sg[0].page = virt_to_page(tmp);
+ sg[0].offset = ((long) tmp & ~PAGE_MASK);
+ sg[0].length = sizeof(tmp);
+
tmp[0]=saddr;
tmp[1]=daddr;
tmp[2]=(sport << 16) + dport;
- SHATransform(tmp+16, tmp);
- seq = tmp[17] + sseq + (count << COOKIEBITS);
+
+ memcpy(tmp+3, syncookie_secret[0], sizeof(syncookie_secret[0]));

+ tfm = get_cpu_var(sha_tfm);


+ crypto_digest_digest(tfm, sg, 1, (char *)hash);
+
+ seq = hash[1] + sseq + (count << COOKIEBITS);

memcpy(tmp+3, syncookie_secret[1], sizeof(syncookie_secret[1]));
- tmp[0]=saddr;
- tmp[1]=daddr;
- tmp[2]=(sport << 16) + dport;
tmp[3] = count; /* minute counter */
- SHATransform(tmp+16, tmp);
+ crypto_digest_digest(tfm, sg, 1, (char *)hash);

+ put_cpu_var(sha_tfm);



/* Add in the second hash and the data */
- return seq + ((tmp[17] + data) & COOKIEMASK);
+ return seq + ((hash[1] + data) & COOKIEMASK);
}

/*

@@ -1892,19 +1804,30 @@

+ tfm = get_cpu_var(sha_tfm);


+ crypto_digest_digest(tfm, sg, 1, (char *)hash);

+ put_cpu_var(sha_tfm);


+
+ cookie -= hash[1] + sseq;
/* Cookie is now reduced to (count * 2^24) ^ (hash % 2^24) */

diff = (count - (cookie >> COOKIEBITS)) & ((__u32)-1 >> COOKIEBITS);

@@ -1912,13 +1835,12 @@


return (__u32)-1;

memcpy(tmp+3, syncookie_secret[1], sizeof(syncookie_secret[1]));
- tmp[0] = saddr;
- tmp[1] = daddr;
- tmp[2] = (sport << 16) + dport;
tmp[3] = count - diff; /* minute counter */
- SHATransform(tmp+16, tmp);

+ tfm = get_cpu_var(sha_tfm);


+ crypto_digest_digest(tfm, sg, 1, (char *)hash);

+ put_cpu_var(sha_tfm);



- return (cookie - tmp[17]) & COOKIEMASK; /* Leaving the data behind */
+ return (cookie - hash[1]) & COOKIEMASK; /* Leaving the data behind */
}
#endif

--
Matt Mackall : http://www.selenic.com : of or relating to the moon

YOSHIFUJI Hideaki / 吉藤英明

unread,
Aug 10, 2003, 4:40:04 AM8/10/03
to
In article <20030810081...@waste.org> (at Sun, 10 Aug 2003 03:15:29 -0500), Matt Mackall <m...@selenic.com> says:

:


> + sg[0].page = virt_to_page(tmp);
> + sg[0].offset = ((long) tmp & ~PAGE_MASK);
> + sg[0].length = sizeof(tmp);

BTW, we spread ((long) ptr & ~PAGE_MASK); it seems ugly.
Why don't we have vert_to_offset(ptr) or something like this?
#define virt_to_offset(ptr) ((unsigned long) (ptr) & ~PAGE_MASK)
Is this bad idea?

--
Hideaki YOSHIFUJI @ USAGI Project <yosh...@linux-ipv6.org>
GPG FP: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA

David S. Miller

unread,
Aug 10, 2003, 4:40:08 AM8/10/03
to
On Sun, 10 Aug 2003 17:32:15 +0900 (JST)
YOSHIFUJI Hideaki / _$B5HF#1QL@ <yosh...@linux-ipv6.org> wrote:

> BTW, we spread ((long) ptr & ~PAGE_MASK); it seems ugly.
> Why don't we have vert_to_offset(ptr) or something like this?
> #define virt_to_offset(ptr) ((unsigned long) (ptr) & ~PAGE_MASK)
> Is this bad idea?

With some name like "virt_to_pageoff()" it sounds like a great
idea.

Matt Mackall

unread,
Aug 10, 2003, 5:10:12 AM8/10/03
to
On Sun, Aug 10, 2003 at 01:30:41AM -0700, David S. Miller wrote:
> On Sun, 10 Aug 2003 17:32:15 +0900 (JST)
> YOSHIFUJI Hideaki / _$B5HF#1QL@ <yosh...@linux-ipv6.org> wrote:
>
> > BTW, we spread ((long) ptr & ~PAGE_MASK); it seems ugly.
> > Why don't we have vert_to_offset(ptr) or something like this?
> > #define virt_to_offset(ptr) ((unsigned long) (ptr) & ~PAGE_MASK)
> > Is this bad idea?
>
> With some name like "virt_to_pageoff()" it sounds like a great
> idea.

Had the same thought. Nowhere good to stick it, so I put it in mm.

diff -urN -X dontdiff orig/include/linux/mm.h work/include/linux/mm.h
--- orig/include/linux/mm.h 2003-08-10 03:16:39.000000000 -0500
+++ work/include/linux/mm.h 2003-08-10 04:03:25.000000000 -0500
@@ -400,6 +400,8 @@
#define VM_FAULT_MINOR 1
#define VM_FAULT_MAJOR 2

+#define virt_to_pageoff(p) ((unsigned long)(p) & ~PAGE_MASK)
+
extern void show_free_areas(void);

struct page *shmem_nopage(struct vm_area_struct * vma,


> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majo...@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/

--

Matt Mackall : http://www.selenic.com : of or relating to the moon

YOSHIFUJI Hideaki / 吉藤英明

unread,
Aug 10, 2003, 5:10:11 AM8/10/03
to
In article <20030810013041...@redhat.com> (at Sun, 10 Aug 2003 01:30:41 -0700), "David S. Miller" <da...@redhat.com> says:

> > BTW, we spread ((long) ptr & ~PAGE_MASK); it seems ugly.
> > Why don't we have vert_to_offset(ptr) or something like this?
> > #define virt_to_offset(ptr) ((unsigned long) (ptr) & ~PAGE_MASK)
> > Is this bad idea?
>
> With some name like "virt_to_pageoff()" it sounds like a great
> idea.

Okay. How about this?
(I'm going to do the actual conversion soon.)

Index: linux-2.6/include/asm-alpha/mmzone.h
===================================================================
RCS file: /home/cvs/linux-2.5/include/asm-alpha/mmzone.h,v
retrieving revision 1.9
diff -u -r1.9 mmzone.h
--- linux-2.6/include/asm-alpha/mmzone.h 3 Jul 2003 05:47:43 -0000 1.9
+++ linux-2.6/include/asm-alpha/mmzone.h 10 Aug 2003 07:30:53 -0000
@@ -77,6 +77,7 @@
NODE_DATA(kvaddr_to_nid(kaddr))->valid_addr_bitmap)

#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define virt_to_pageoff(kaddr) ((unsigned long)(kaddr) & ~PAGE_MASK)

#define VALID_PAGE(page) (((page) - mem_map) < max_mapnr)

Index: linux-2.6/include/asm-alpha/page.h
===================================================================
RCS file: /home/cvs/linux-2.5/include/asm-alpha/page.h,v
retrieving revision 1.12
diff -u -r1.12 page.h
--- linux-2.6/include/asm-alpha/page.h 13 Jan 2003 23:24:04 -0000 1.12
+++ linux-2.6/include/asm-alpha/page.h 10 Aug 2003 07:30:53 -0000
@@ -90,6 +90,7 @@
#define pfn_to_page(pfn) (mem_map + (pfn))
#define page_to_pfn(page) ((unsigned long)((page) - mem_map))
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define virt_to_pageoff(kaddr) ((unsigned long)(kaddr) & ~PAGE_MASK)

#define pfn_valid(pfn) ((pfn) < max_mapnr)
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
Index: linux-2.6/include/asm-arm26/memory.h
===================================================================
RCS file: /home/cvs/linux-2.5/include/asm-arm26/memory.h,v
retrieving revision 1.2
diff -u -r1.2 memory.h
--- linux-2.6/include/asm-arm26/memory.h 8 Jun 2003 16:21:42 -0000 1.2
+++ linux-2.6/include/asm-arm26/memory.h 10 Aug 2003 07:30:53 -0000
@@ -86,6 +86,7 @@
#define pfn_valid(pfn) ((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr))

#define virt_to_page(kaddr) (pfn_to_page(__pa(kaddr) >> PAGE_SHIFT))
+#define virt_to_pageoff(kaddr) ((unsigned long)(kaddr) & ~PAGE_MASK)
#define virt_addr_valid(kaddr) ((int)(kaddr) >= PAGE_OFFSET && (int)(kaddr) < (unsigned long)high_memory)

/*
Index: linux-2.6/include/asm-cris/page.h
===================================================================
RCS file: /home/cvs/linux-2.5/include/asm-cris/page.h,v
retrieving revision 1.7
diff -u -r1.7 page.h
--- linux-2.6/include/asm-cris/page.h 10 Jul 2003 17:33:07 -0000 1.7
+++ linux-2.6/include/asm-cris/page.h 10 Aug 2003 07:30:53 -0000
@@ -50,6 +50,7 @@
*/

#define virt_to_page(kaddr) (mem_map + (((unsigned long)(kaddr) - PAGE_OFFSET) >> PAGE_SHIFT))
+#define virt_to_pageoff(kaddr) ((unsigned long)(kaddr) & ~PAGE_MASK)
#define VALID_PAGE(page) (((page) - mem_map) < max_mapnr)
#define virt_addr_valid(kaddr) pfn_valid((kaddr) >> PAGE_SHIFT)

Index: linux-2.6/include/asm-h8300/page.h
===================================================================
RCS file: /home/cvs/linux-2.5/include/asm-h8300/page.h,v
retrieving revision 1.2
diff -u -r1.2 page.h
--- linux-2.6/include/asm-h8300/page.h 17 Apr 2003 23:27:57 -0000 1.2
+++ linux-2.6/include/asm-h8300/page.h 10 Aug 2003 07:30:53 -0000
@@ -84,7 +84,7 @@

#define MAP_NR(addr) (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)
#define virt_to_page(addr) (mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT))
-#define virt_to_page(addr) (mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT))
+#define virt_to_pageoff(kaddr) ((unsigned long)(kaddr) & ~PAGE_MASK)
#define page_to_virt(page) ((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)
#define VALID_PAGE(page) ((page - mem_map) < max_mapnr)

Index: linux-2.6/include/asm-i386/page.h
===================================================================
RCS file: /home/cvs/linux-2.5/include/asm-i386/page.h,v
retrieving revision 1.25
diff -u -r1.25 page.h
--- linux-2.6/include/asm-i386/page.h 31 Mar 2003 22:29:20 -0000 1.25
+++ linux-2.6/include/asm-i386/page.h 10 Aug 2003 07:30:53 -0000
@@ -133,6 +133,7 @@
#define pfn_valid(pfn) ((pfn) < max_mapnr)
#endif /* !CONFIG_DISCONTIGMEM */
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define virt_to_pageoff(kaddr) ((unsigned long)(kaddr) & ~PAGE_MASK)

#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)

Index: linux-2.6/include/asm-ia64/mmzone.h
===================================================================
RCS file: /home/cvs/linux-2.5/include/asm-ia64/mmzone.h,v
retrieving revision 1.5
diff -u -r1.5 mmzone.h
--- linux-2.6/include/asm-ia64/mmzone.h 6 Mar 2003 21:34:32 -0000 1.5
+++ linux-2.6/include/asm-ia64/mmzone.h 10 Aug 2003 07:30:53 -0000
@@ -63,6 +63,7 @@
(VALID_MEM_KADDR(_kvtp)) \
? BANK_MEM_MAP_BASE(_kvtp) + BANK_MAP_NR(_kvtp) \
: NULL;})
+#define virt_to_pageoff(kaddr) ((unsigned long)(kaddr) & ~PAGE_MASK)

/*
* Given a page struct entry, return the physical address that the page struct represents.
Index: linux-2.6/include/asm-ia64/page.h
===================================================================
RCS file: /home/cvs/linux-2.5/include/asm-ia64/page.h,v
retrieving revision 1.18
diff -u -r1.18 page.h
--- linux-2.6/include/asm-ia64/page.h 21 Jun 2003 16:19:17 -0000 1.18
+++ linux-2.6/include/asm-ia64/page.h 10 Aug 2003 07:30:53 -0000
@@ -101,6 +101,7 @@
# define pfn_valid(pfn) ((pfn) < max_mapnr)
# endif
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define virt_to_pageoff(kaddr) ((unsigned long)(kaddr) & ~PAGE_MASK)
#define page_to_pfn(page) ((unsigned long) (page - mem_map))
#define pfn_to_page(pfn) (mem_map + (pfn))
#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
Index: linux-2.6/include/asm-m68k/page.h
===================================================================
RCS file: /home/cvs/linux-2.5/include/asm-m68k/page.h,v
retrieving revision 1.11
diff -u -r1.11 page.h
--- linux-2.6/include/asm-m68k/page.h 13 Apr 2003 09:55:02 -0000 1.11
+++ linux-2.6/include/asm-m68k/page.h 10 Aug 2003 07:30:53 -0000
@@ -179,6 +179,7 @@
#define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT)

#define virt_to_page(kaddr) (mem_map + (((unsigned long)(kaddr)-PAGE_OFFSET) >> PAGE_SHIFT))
+#define virt_to_pageoff(kaddr) ((unsigned long)(kaddr) & ~PAGE_MASK)
#define page_to_virt(page) ((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)

#define pfn_to_page(pfn) virt_to_page(pfn_to_virt(pfn))
Index: linux-2.6/include/asm-m68knommu/page.h
===================================================================
RCS file: /home/cvs/linux-2.5/include/asm-m68knommu/page.h,v
retrieving revision 1.4
diff -u -r1.4 page.h
--- linux-2.6/include/asm-m68knommu/page.h 7 Jul 2003 00:20:14 -0000 1.4
+++ linux-2.6/include/asm-m68knommu/page.h 10 Aug 2003 07:30:53 -0000
@@ -85,6 +85,7 @@
#define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT)

#define virt_to_page(addr) (mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT))
+#define virt_to_pageoff(kaddr) ((unsigned long)(kaddr) & ~PAGE_MASK)
#define page_to_virt(page) ((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)
#define VALID_PAGE(page) ((page - mem_map) < max_mapnr)

Index: linux-2.6/include/asm-mips/mmzone.h
===================================================================
RCS file: /home/cvs/linux-2.5/include/asm-mips/mmzone.h,v
retrieving revision 1.2
diff -u -r1.2 mmzone.h
--- linux-2.6/include/asm-mips/mmzone.h 1 Aug 2003 05:40:55 -0000 1.2
+++ linux-2.6/include/asm-mips/mmzone.h 10 Aug 2003 07:30:54 -0000
@@ -84,6 +84,7 @@
((((page)-(page)->zone->zone_mem_map) + (page)->zone->zone_start_pfn) \
<< PAGE_SHIFT)
#define virt_to_page(kaddr) pfn_to_page(MIPS64_NR(kaddr))
+#define virt_to_pageoff(kaddr) ((unsigned long)(kaddr) & ~PAGE_MASK)

#define pfn_valid(pfn) ((pfn) < max_mapnr)
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
Index: linux-2.6/include/asm-mips/page.h
===================================================================
RCS file: /home/cvs/linux-2.5/include/asm-mips/page.h,v
retrieving revision 1.7
diff -u -r1.7 page.h
--- linux-2.6/include/asm-mips/page.h 1 Aug 2003 05:40:55 -0000 1.7
+++ linux-2.6/include/asm-mips/page.h 10 Aug 2003 07:30:54 -0000
@@ -115,6 +115,7 @@
#define pfn_to_page(pfn) (mem_map + (pfn))
#define page_to_pfn(page) ((unsigned long)((page) - mem_map))
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define virt_to_pageoff(kaddr) ((unsigned long)(kaddr) & ~PAGE_MASK)

#define pfn_valid(pfn) ((pfn) < max_mapnr)
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
Index: linux-2.6/include/asm-parisc/mmzone.h
===================================================================
RCS file: /home/cvs/linux-2.5/include/asm-parisc/mmzone.h,v
retrieving revision 1.2
diff -u -r1.2 mmzone.h
--- linux-2.6/include/asm-parisc/mmzone.h 30 Oct 2002 23:00:20 -0000 1.2
+++ linux-2.6/include/asm-parisc/mmzone.h 10 Aug 2003 07:30:54 -0000
@@ -24,6 +24,7 @@
+ ((paddr) >> PAGE_SHIFT))

#define virt_to_page(kvaddr) phys_to_page(__pa(kvaddr))
+#define virt_to_pageoff(kaddr) ((unsigned long)(kaddr) & ~PAGE_MASK)

/* This is kind of bogus, need to investigate performance of doing it right */
#define VALID_PAGE(page) ((page - mem_map) < max_mapnr)
Index: linux-2.6/include/asm-parisc/page.h
===================================================================
RCS file: /home/cvs/linux-2.5/include/asm-parisc/page.h,v
retrieving revision 1.5
diff -u -r1.5 page.h
--- linux-2.6/include/asm-parisc/page.h 13 Jan 2003 23:24:04 -0000 1.5
+++ linux-2.6/include/asm-parisc/page.h 10 Aug 2003 07:30:54 -0000
@@ -106,6 +106,7 @@

#ifndef CONFIG_DISCONTIGMEM
#define virt_to_page(kaddr) (mem_map + (__pa(kaddr) >> PAGE_SHIFT))
+#define virt_to_pageoff(kaddr) ((unsigned long)(kaddr) & ~PAGE_MASK)
#define VALID_PAGE(page) ((page - mem_map) < max_mapnr)
#endif /* !CONFIG_DISCONTIGMEM */

Index: linux-2.6/include/asm-ppc/page.h
===================================================================
RCS file: /home/cvs/linux-2.5/include/asm-ppc/page.h,v
retrieving revision 1.14
diff -u -r1.14 page.h
--- linux-2.6/include/asm-ppc/page.h 26 Feb 2003 03:12:12 -0000 1.14
+++ linux-2.6/include/asm-ppc/page.h 10 Aug 2003 07:30:54 -0000
@@ -123,6 +123,7 @@
#define pfn_to_page(pfn) (mem_map + ((pfn) - PPC_PGSTART))
#define page_to_pfn(page) ((unsigned long)((page) - mem_map) + PPC_PGSTART)
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define virt_to_pageoff(kaddr) ((unsigned long)(kaddr) & ~PAGE_MASK)

#define pfn_valid(pfn) (((pfn) - PPC_PGSTART) < max_mapnr)
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
Index: linux-2.6/include/asm-ppc64/page.h
===================================================================
RCS file: /home/cvs/linux-2.5/include/asm-ppc64/page.h,v
retrieving revision 1.14
diff -u -r1.14 page.h
--- linux-2.6/include/asm-ppc64/page.h 5 May 2003 00:57:02 -0000 1.14
+++ linux-2.6/include/asm-ppc64/page.h 10 Aug 2003 07:30:54 -0000
@@ -198,6 +198,7 @@
#endif

#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define virt_to_pageoff(kaddr) ((unsigned long)(kaddr) & ~PAGE_MASK)

#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)

Index: linux-2.6/include/asm-s390/page.h
===================================================================
RCS file: /home/cvs/linux-2.5/include/asm-s390/page.h,v
retrieving revision 1.10
diff -u -r1.10 page.h
--- linux-2.6/include/asm-s390/page.h 14 Apr 2003 18:27:30 -0000 1.10
+++ linux-2.6/include/asm-s390/page.h 10 Aug 2003 07:30:54 -0000
@@ -174,6 +174,7 @@
#define pfn_to_page(pfn) (mem_map + (pfn))
#define page_to_pfn(page) ((unsigned long)((page) - mem_map))
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define virt_to_pageoff(kaddr) ((unsigned long)(kaddr) & ~PAGE_MASK)

#define pfn_valid(pfn) ((pfn) < max_mapnr)
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
Index: linux-2.6/include/asm-sh/page.h
===================================================================
RCS file: /home/cvs/linux-2.5/include/asm-sh/page.h,v
retrieving revision 1.5
diff -u -r1.5 page.h
--- linux-2.6/include/asm-sh/page.h 2 Jul 2003 05:34:18 -0000 1.5
+++ linux-2.6/include/asm-sh/page.h 10 Aug 2003 07:30:54 -0000
@@ -94,6 +94,7 @@
#define pfn_to_page(pfn) (mem_map + (pfn) - PFN_START)
#define page_to_pfn(page) ((unsigned long)((page) - mem_map) + PFN_START)
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define virt_to_pageoff(kaddr) ((unsigned long)(kaddr) & ~PAGE_MASK)
#define pfn_valid(pfn) (((pfn) - PFN_START) < max_mapnr)
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)

Index: linux-2.6/include/asm-sparc/page.h
===================================================================
RCS file: /home/cvs/linux-2.5/include/asm-sparc/page.h,v
retrieving revision 1.10
diff -u -r1.10 page.h
--- linux-2.6/include/asm-sparc/page.h 3 May 2003 17:28:36 -0000 1.10
+++ linux-2.6/include/asm-sparc/page.h 10 Aug 2003 07:30:54 -0000
@@ -165,6 +165,7 @@
#define pfn_to_page(pfn) (mem_map + (pfn))
#define page_to_pfn(page) ((unsigned long)((page) - mem_map))
#define virt_to_page(kaddr) (mem_map + (__pa(kaddr) >> PAGE_SHIFT))
+#define virt_to_pageoff(kaddr) ((unsigned long)(kaddr) & ~PAGE_MASK)
#define pfn_valid(pfn) ((pfn) < max_mapnr)
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)

Index: linux-2.6/include/asm-sparc64/page.h
===================================================================
RCS file: /home/cvs/linux-2.5/include/asm-sparc64/page.h,v
retrieving revision 1.13
diff -u -r1.13 page.h
--- linux-2.6/include/asm-sparc64/page.h 13 Jan 2003 23:24:04 -0000 1.13
+++ linux-2.6/include/asm-sparc64/page.h 10 Aug 2003 07:30:54 -0000
@@ -123,6 +123,7 @@
#define pfn_to_page(pfn) (mem_map + ((pfn)-(pfn_base)))
#define page_to_pfn(page) ((unsigned long)(((page) - mem_map) + pfn_base))
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr)>>PAGE_SHIFT)
+#define virt_to_pageoff(kaddr) ((unsigned long)(kaddr) & ~PAGE_MASK)

#define pfn_valid(pfn) (((pfn)-(pfn_base)) < max_mapnr)
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
Index: linux-2.6/include/asm-um/page.h
===================================================================
RCS file: /home/cvs/linux-2.5/include/asm-um/page.h,v
retrieving revision 1.5
diff -u -r1.5 page.h
--- linux-2.6/include/asm-um/page.h 6 Feb 2003 04:13:38 -0000 1.5
+++ linux-2.6/include/asm-um/page.h 10 Aug 2003 07:30:54 -0000
@@ -36,6 +36,7 @@
extern struct page *phys_to_page(unsigned long phys);

#define virt_to_page(v) (phys_to_page(__pa(v)))
+#define virt_to_pageoff(kaddr) ((unsigned long)(kaddr) & ~PAGE_MASK)

extern struct page *page_mem_map(struct page *page);

Index: linux-2.6/include/asm-v850/page.h
===================================================================
RCS file: /home/cvs/linux-2.5/include/asm-v850/page.h,v
retrieving revision 1.4
diff -u -r1.4 page.h
--- linux-2.6/include/asm-v850/page.h 13 Apr 2003 09:55:02 -0000 1.4
+++ linux-2.6/include/asm-v850/page.h 10 Aug 2003 07:30:54 -0000
@@ -127,6 +127,7 @@
#define MAP_NR(kaddr) \
(((unsigned long)(kaddr) - PAGE_OFFSET) >> PAGE_SHIFT)
#define virt_to_page(kaddr) (mem_map + MAP_NR (kaddr))
+#define virt_to_pageoff(kaddr) ((unsigned long)(kaddr) & ~PAGE_MASK)
#define page_to_virt(page) \
((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)

Index: linux-2.6/include/asm-x86_64/page.h
===================================================================
RCS file: /home/cvs/linux-2.5/include/asm-x86_64/page.h,v
retrieving revision 1.12
diff -u -r1.12 page.h
--- linux-2.6/include/asm-x86_64/page.h 21 Jun 2003 16:18:33 -0000 1.12
+++ linux-2.6/include/asm-x86_64/page.h 10 Aug 2003 07:30:54 -0000
@@ -122,6 +122,7 @@
#endif

#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define virt_to_pageoff(kaddr) ((unsigned long)(kaddr) & ~PAGE_MASK)
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)

--
Hideaki YOSHIFUJI @ USAGI Project <yosh...@linux-ipv6.org>
GPG FP: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA

David S. Miller

unread,
Aug 10, 2003, 5:20:08 AM8/10/03
to
On Sun, 10 Aug 2003 04:05:56 -0500
Matt Mackall <m...@selenic.com> wrote:

> > With some name like "virt_to_pageoff()" it sounds like a great
> > idea.
>
> Had the same thought. Nowhere good to stick it, so I put it in mm.

That looks fine to me.

Yoshfuji, feel free to do your conversions, and use this
linux/mm.h placement of the virt_to_pageoff() macro instead
of having to put it into every asm header.

YOSHIFUJI Hideaki / 吉藤英明

unread,
Aug 10, 2003, 7:10:07 AM8/10/03
to
[2/9] convert cryptoapi to virt_to_pageoff().

Index: linux-2.6/crypto/hmac.c
===================================================================
RCS file: /home/cvs/linux-2.5/crypto/hmac.c,v
retrieving revision 1.3
diff -u -r1.3 hmac.c
--- linux-2.6/crypto/hmac.c 19 Nov 2002 03:02:31 -0000 1.3
+++ linux-2.6/crypto/hmac.c 10 Aug 2003 08:40:52 -0000
@@ -26,7 +26,7 @@
struct scatterlist tmp;

tmp.page = virt_to_page(key);
- tmp.offset = ((long)key & ~PAGE_MASK);
+ tmp.offset = virt_to_pageoff(key);
tmp.length = keylen;
crypto_digest_digest(tfm, &tmp, 1, key);

@@ -71,7 +71,7 @@
ipad[i] ^= 0x36;

tmp.page = virt_to_page(ipad);
- tmp.offset = ((long)ipad & ~PAGE_MASK);
+ tmp.offset = virt_to_pageoff(ipad);
tmp.length = crypto_tfm_alg_blocksize(tfm);

crypto_digest_init(tfm);
@@ -105,14 +105,14 @@
opad[i] ^= 0x5c;

tmp.page = virt_to_page(opad);
- tmp.offset = ((long)opad & ~PAGE_MASK);
+ tmp.offset = virt_to_pageoff(opad);
tmp.length = crypto_tfm_alg_blocksize(tfm);

crypto_digest_init(tfm);
crypto_digest_update(tfm, &tmp, 1);

tmp.page = virt_to_page(out);
- tmp.offset = ((long)out & ~PAGE_MASK);
+ tmp.offset = virt_to_pageoff(out);
tmp.length = crypto_tfm_alg_digestsize(tfm);

crypto_digest_update(tfm, &tmp, 1);
Index: linux-2.6/crypto/tcrypt.c
===================================================================
RCS file: /home/cvs/linux-2.5/crypto/tcrypt.c,v
retrieving revision 1.13
diff -u -r1.13 tcrypt.c
--- linux-2.6/crypto/tcrypt.c 1 Aug 2003 22:02:12 -0000 1.13
+++ linux-2.6/crypto/tcrypt.c 10 Aug 2003 08:40:52 -0000
@@ -96,7 +96,7 @@

p = md5_tv[i].plaintext;
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = strlen(md5_tv[i].plaintext);

crypto_digest_init(tfm);
@@ -119,12 +119,12 @@

p = &xbuf[IDX1];
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = 13;

p = &xbuf[IDX2];
sg[1].page = virt_to_page(p);
- sg[1].offset = ((long) p & ~PAGE_MASK);
+ sg[1].offset = virt_to_pageoff(p);
sg[1].length = 13;

memset(result, 0, sizeof (result));
@@ -173,7 +173,7 @@

p = hmac_md5_tv[i].plaintext;
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = strlen(hmac_md5_tv[i].plaintext);

klen = strlen(hmac_md5_tv[i].key);
@@ -195,12 +195,12 @@

p = &xbuf[IDX1];
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = 16;

p = &xbuf[IDX2];
sg[1].page = virt_to_page(p);
- sg[1].offset = ((long) p & ~PAGE_MASK);
+ sg[1].offset = virt_to_pageoff(p);
sg[1].length = 12;

memset(result, 0, sizeof (result));
@@ -250,7 +250,7 @@

p = hmac_sha1_tv[i].plaintext;
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = strlen(hmac_sha1_tv[i].plaintext);

klen = strlen(hmac_sha1_tv[i].key);
@@ -274,12 +274,12 @@

p = &xbuf[IDX1];
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = 16;

p = &xbuf[IDX2];
sg[1].page = virt_to_page(p);
- sg[1].offset = ((long) p & ~PAGE_MASK);
+ sg[1].offset = virt_to_pageoff(p);
sg[1].length = 12;

memset(result, 0, sizeof (result));
@@ -329,7 +329,7 @@

p = hmac_sha256_tv[i].plaintext;
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = strlen(hmac_sha256_tv[i].plaintext);

klen = strlen(hmac_sha256_tv[i].key);
@@ -383,7 +383,7 @@

p = md4_tv[i].plaintext;
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = strlen(md4_tv[i].plaintext);

crypto_digest_digest(tfm, sg, 1, result);
@@ -433,7 +433,7 @@

p = sha1_tv[i].plaintext;
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = strlen(sha1_tv[i].plaintext);

crypto_digest_init(tfm);
@@ -456,12 +456,12 @@

p = &xbuf[IDX1];
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = 28;

p = &xbuf[IDX2];
sg[1].page = virt_to_page(p);
- sg[1].offset = ((long) p & ~PAGE_MASK);
+ sg[1].offset = virt_to_pageoff(p);
sg[1].length = 28;

memset(result, 0, sizeof (result));
@@ -508,7 +508,7 @@

p = sha256_tv[i].plaintext;
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = strlen(sha256_tv[i].plaintext);

crypto_digest_init(tfm);
@@ -531,12 +531,12 @@

p = &xbuf[IDX1];
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = 28;

p = &xbuf[IDX2];
sg[1].page = virt_to_page(p);
- sg[1].offset = ((long) p & ~PAGE_MASK);
+ sg[1].offset = virt_to_pageoff(p);
sg[1].length = 28;

memset(result, 0, sizeof (result));
@@ -584,7 +584,7 @@

p = sha384_tv[i].plaintext;
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = strlen(sha384_tv[i].plaintext);

crypto_digest_init(tfm);
@@ -636,7 +636,7 @@

p = sha512_tv[i].plaintext;
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = strlen(sha512_tv[i].plaintext);

crypto_digest_init(tfm);
@@ -701,7 +701,7 @@

p = des_tv[i].plaintext;
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = len;
ret = crypto_cipher_encrypt(tfm, sg, sg, len);
if (ret) {
@@ -738,12 +738,12 @@

p = &xbuf[IDX1];
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = 8;

p = &xbuf[IDX2];
sg[1].page = virt_to_page(p);
- sg[1].offset = ((long) p & ~PAGE_MASK);
+ sg[1].offset = virt_to_pageoff(p);
sg[1].length = 8;

ret = crypto_cipher_encrypt(tfm, sg, sg, 16);
@@ -801,17 +801,17 @@

p = &xbuf[IDX3];
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = 14;

p = &xbuf[IDX4];
sg[1].page = virt_to_page(p);
- sg[1].offset = ((long) p & ~PAGE_MASK);
+ sg[1].offset = virt_to_pageoff(p);
sg[1].length = 10;

p = &xbuf[IDX5];
sg[2].page = virt_to_page(p);
- sg[2].offset = ((long) p & ~PAGE_MASK);
+ sg[2].offset = virt_to_pageoff(p);
sg[2].length = 8;

ret = crypto_cipher_encrypt(tfm, sg, sg, 32);
@@ -872,22 +872,22 @@

p = &xbuf[IDX3];
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = 2;

p = &xbuf[IDX4];
sg[1].page = virt_to_page(p);
- sg[1].offset = ((long) p & ~PAGE_MASK);
+ sg[1].offset = virt_to_pageoff(p);
sg[1].length = 1;

p = &xbuf[IDX5];
sg[2].page = virt_to_page(p);
- sg[2].offset = ((long) p & ~PAGE_MASK);
+ sg[2].offset = virt_to_pageoff(p);
sg[2].length = 3;

p = &xbuf[IDX6];
sg[3].page = virt_to_page(p);
- sg[3].offset = ((long) p & ~PAGE_MASK);
+ sg[3].offset = virt_to_pageoff(p);
sg[3].length = 18;

ret = crypto_cipher_encrypt(tfm, sg, sg, 24);
@@ -956,27 +956,27 @@

p = &xbuf[IDX3];
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = 2;

p = &xbuf[IDX4];
sg[1].page = virt_to_page(p);
- sg[1].offset = ((long) p & ~PAGE_MASK);
+ sg[1].offset = virt_to_pageoff(p);
sg[1].length = 2;

p = &xbuf[IDX5];
sg[2].page = virt_to_page(p);
- sg[2].offset = ((long) p & ~PAGE_MASK);
+ sg[2].offset = virt_to_pageoff(p);
sg[2].length = 2;

p = &xbuf[IDX6];
sg[3].page = virt_to_page(p);
- sg[3].offset = ((long) p & ~PAGE_MASK);
+ sg[3].offset = virt_to_pageoff(p);
sg[3].length = 2;

p = &xbuf[IDX7];
sg[4].page = virt_to_page(p);
- sg[4].offset = ((long) p & ~PAGE_MASK);
+ sg[4].offset = virt_to_pageoff(p);
sg[4].length = 8;

ret = crypto_cipher_encrypt(tfm, sg, sg, 16);
@@ -1040,42 +1040,42 @@

p = &xbuf[IDX1];
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = 1;

p = &xbuf[IDX2];
sg[1].page = virt_to_page(p);
- sg[1].offset = ((long) p & ~PAGE_MASK);
+ sg[1].offset = virt_to_pageoff(p);
sg[1].length = 1;

p = &xbuf[IDX3];
sg[2].page = virt_to_page(p);
- sg[2].offset = ((long) p & ~PAGE_MASK);
+ sg[2].offset = virt_to_pageoff(p);
sg[2].length = 1;

p = &xbuf[IDX4];
sg[3].page = virt_to_page(p);
- sg[3].offset = ((long) p & ~PAGE_MASK);
+ sg[3].offset = virt_to_pageoff(p);
sg[3].length = 1;

p = &xbuf[IDX5];
sg[4].page = virt_to_page(p);
- sg[4].offset = ((long) p & ~PAGE_MASK);
+ sg[4].offset = virt_to_pageoff(p);
sg[4].length = 1;

p = &xbuf[IDX6];
sg[5].page = virt_to_page(p);
- sg[5].offset = ((long) p & ~PAGE_MASK);
+ sg[5].offset = virt_to_pageoff(p);
sg[5].length = 1;

p = &xbuf[IDX7];
sg[6].page = virt_to_page(p);
- sg[6].offset = ((long) p & ~PAGE_MASK);
+ sg[6].offset = virt_to_pageoff(p);
sg[6].length = 1;

p = &xbuf[IDX8];
sg[7].page = virt_to_page(p);
- sg[7].offset = ((long) p & ~PAGE_MASK);
+ sg[7].offset = virt_to_pageoff(p);
sg[7].length = 1;

ret = crypto_cipher_encrypt(tfm, sg, sg, 8);
@@ -1117,7 +1117,7 @@

p = des_tv[i].plaintext;
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = len;

ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
@@ -1155,12 +1155,12 @@

p = &xbuf[IDX1];
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = 8;

p = &xbuf[IDX2];
sg[1].page = virt_to_page(p);
- sg[1].offset = ((long) p & ~PAGE_MASK);
+ sg[1].offset = virt_to_pageoff(p);
sg[1].length = 8;

ret = crypto_cipher_decrypt(tfm, sg, sg, 16);
@@ -1207,17 +1207,17 @@

p = &xbuf[IDX1];
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = 3;

p = &xbuf[IDX2];
sg[1].page = virt_to_page(p);
- sg[1].offset = ((long) p & ~PAGE_MASK);
+ sg[1].offset = virt_to_pageoff(p);
sg[1].length = 12;

p = &xbuf[IDX3];
sg[2].page = virt_to_page(p);
- sg[2].offset = ((long) p & ~PAGE_MASK);
+ sg[2].offset = virt_to_pageoff(p);
sg[2].length = 1;

ret = crypto_cipher_decrypt(tfm, sg, sg, 16);
@@ -1284,7 +1284,7 @@
p = des_tv[i].plaintext;

sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = len;

crypto_cipher_set_iv(tfm, des_tv[i].iv,
@@ -1339,12 +1339,12 @@

p = &xbuf[IDX1];
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = 13;

p = &xbuf[IDX2];
sg[1].page = virt_to_page(p);
- sg[1].offset = ((long) p & ~PAGE_MASK);
+ sg[1].offset = virt_to_pageoff(p);
sg[1].length = 11;

crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm));
@@ -1392,7 +1392,7 @@
p = des_tv[i].plaintext;

sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = len;

crypto_cipher_set_iv(tfm, des_tv[i].iv,
@@ -1440,12 +1440,12 @@

p = &xbuf[IDX1];
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = 4;

p = &xbuf[IDX2];
sg[1].page = virt_to_page(p);
- sg[1].offset = ((long) p & ~PAGE_MASK);
+ sg[1].offset = virt_to_pageoff(p);
sg[1].length = 4;

crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm));
@@ -1516,7 +1516,7 @@

p = des_tv[i].plaintext;
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = len;
ret = crypto_cipher_encrypt(tfm, sg, sg, len);
if (ret) {
@@ -1559,7 +1559,7 @@

p = des_tv[i].plaintext;
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = len;
ret = crypto_cipher_decrypt(tfm, sg, sg, len);
if (ret) {
@@ -1622,7 +1622,7 @@

p = bf_tv[i].plaintext;
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = bf_tv[i].plen;
ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
if (ret) {
@@ -1664,7 +1664,7 @@

p = bf_tv[i].plaintext;
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = bf_tv[i].plen;
ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
if (ret) {
@@ -1713,7 +1713,7 @@
p = bf_tv[i].plaintext;

sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = bf_tv[i].plen;

crypto_cipher_set_iv(tfm, bf_tv[i].iv,
@@ -1758,7 +1758,7 @@
p = bf_tv[i].plaintext;

sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = bf_tv[i].plen;

crypto_cipher_set_iv(tfm, bf_tv[i].iv,
@@ -1827,7 +1827,7 @@

p = tf_tv[i].plaintext;
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = tf_tv[i].plen;
ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
if (ret) {
@@ -1869,7 +1869,7 @@

p = tf_tv[i].plaintext;
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = tf_tv[i].plen;
ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
if (ret) {
@@ -1918,7 +1918,7 @@
p = tf_tv[i].plaintext;

sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = tf_tv[i].plen;

crypto_cipher_set_iv(tfm, tf_tv[i].iv,
@@ -1964,7 +1964,7 @@
p = tf_tv[i].plaintext;

sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = tf_tv[i].plen;

crypto_cipher_set_iv(tfm, tf_tv[i].iv,
@@ -2028,7 +2028,7 @@

p = serp_tv[i].plaintext;
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = sizeof(serp_tv[i].plaintext);
ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
if (ret) {
@@ -2068,7 +2068,7 @@

p = serp_tv[i].plaintext;
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = sizeof(serp_tv[i].plaintext);
ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
if (ret) {
@@ -2131,7 +2131,7 @@

p = aes_tv[i].plaintext;
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = aes_tv[i].plen;
ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
if (ret) {
@@ -2173,7 +2173,7 @@

p = aes_tv[i].plaintext;
sg[0].page = virt_to_page(p);
- sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(p);
sg[0].length = aes_tv[i].plen;
ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
if (ret) {

--
Hideaki YOSHIFUJI @ USAGI Project <yosh...@linux-ipv6.org>
GPG FP: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA

YOSHIFUJI Hideaki / 吉藤英明

unread,
Aug 10, 2003, 7:10:07 AM8/10/03
to
In article <20030810020444...@redhat.com> (at Sun, 10 Aug 2003 02:04:44 -0700), "David S. Miller" <da...@redhat.com> says:

> Yoshfuji, feel free to do your conversions, and use this
> linux/mm.h placement of the virt_to_pageoff() macro instead
> of having to put it into every asm header.

[1/9] introduce virt_to_pageoff().

Index: linux-2.6/Documentation/DMA-mapping.txt
===================================================================
RCS file: /home/cvs/linux-2.5/Documentation/DMA-mapping.txt,v
retrieving revision 1.17
diff -u -r1.17 DMA-mapping.txt
--- linux-2.6/Documentation/DMA-mapping.txt 1 Aug 2003 19:02:34 -0000 1.17
+++ linux-2.6/Documentation/DMA-mapping.txt 10 Aug 2003 08:40:50 -0000
@@ -689,7 +689,7 @@
and offset using something like this:

struct page *page = virt_to_page(ptr);
- unsigned long offset = ((unsigned long)ptr & ~PAGE_MASK);
+ unsigned long offset = virt_to_pageoff(ptr);

Here are the interfaces:

Index: linux-2.6/include/linux/mm.h
===================================================================
RCS file: /home/cvs/linux-2.5/include/linux/mm.h,v
retrieving revision 1.125
diff -u -r1.125 mm.h
--- linux-2.6/include/linux/mm.h 1 Aug 2003 17:02:32 -0000 1.125
+++ linux-2.6/include/linux/mm.h 10 Aug 2003 08:40:55 -0000


@@ -400,6 +400,8 @@
#define VM_FAULT_MINOR 1
#define VM_FAULT_MAJOR 2

+#define virt_to_pageoff(p) ((unsigned long)(p) & ~PAGE_MASK)
+
extern void show_free_areas(void);

struct page *shmem_nopage(struct vm_area_struct * vma,

--
Hideaki YOSHIFUJI @ USAGI Project <yosh...@linux-ipv6.org>
GPG FP: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA

YOSHIFUJI Hideaki / 吉藤英明

unread,
Aug 10, 2003, 7:10:12 AM8/10/03
to
[3/9] convert net virt_to_pageoff().

Index: linux-2.6/net/ipv6/addrconf.c
===================================================================
RCS file: /home/cvs/linux-2.5/net/ipv6/addrconf.c,v
retrieving revision 1.48
diff -u -r1.48 addrconf.c
--- linux-2.6/net/ipv6/addrconf.c 25 Jul 2003 23:58:59 -0000 1.48
+++ linux-2.6/net/ipv6/addrconf.c 10 Aug 2003 08:40:55 -0000
@@ -1110,10 +1110,10 @@
struct scatterlist sg[2];

sg[0].page = virt_to_page(idev->entropy);
- sg[0].offset = ((long) idev->entropy & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(idev->entropy);


sg[0].length = 8;

sg[1].page = virt_to_page(eui64);
- sg[1].offset = ((long) eui64 & ~PAGE_MASK);
+ sg[1].offset = virt_to_pageoff(eui64);


sg[1].length = 8;

dev = idev->dev;
Index: linux-2.6/net/sunrpc/auth_gss/gss_krb5_crypto.c
===================================================================
RCS file: /home/cvs/linux-2.5/net/sunrpc/auth_gss/gss_krb5_crypto.c,v
retrieving revision 1.3
diff -u -r1.3 gss_krb5_crypto.c
--- linux-2.6/net/sunrpc/auth_gss/gss_krb5_crypto.c 4 Feb 2003 17:55:46 -0000 1.3
+++ linux-2.6/net/sunrpc/auth_gss/gss_krb5_crypto.c 10 Aug 2003 08:40:55 -0000
@@ -75,7 +75,7 @@

memcpy(out, in, length);
sg[0].page = virt_to_page(out);
- sg[0].offset = ((long)out & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(out);
sg[0].length = length;

ret = crypto_cipher_encrypt(tfm, sg, sg, length);
@@ -114,7 +114,7 @@

memcpy(out, in, length);
sg[0].page = virt_to_page(out);
- sg[0].offset = ((long)out & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(out);
sg[0].length = length;

ret = crypto_cipher_decrypt(tfm, sg, sg, length);
@@ -151,7 +151,7 @@
goto out_free_tfm;
}
sg[0].page = virt_to_page(input->data);
- sg[0].offset = ((long)input->data & ~PAGE_MASK);
+ sg[0].offset = virt_to_pageoff(input->data);
sg[0].length = input->len;

crypto_digest_init(tfm);

--
Hideaki YOSHIFUJI @ USAGI Project <yosh...@linux-ipv6.org>
GPG FP: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA

YOSHIFUJI Hideaki / 吉藤英明

unread,
Aug 10, 2003, 7:20:06 AM8/10/03
to
[5/9] convert drivers/ide to virt_to_pageoff().

Index: linux-2.6/drivers/ide/ide-dma.c
===================================================================
RCS file: /home/cvs/linux-2.5/drivers/ide/ide-dma.c,v
retrieving revision 1.60
diff -u -r1.60 ide-dma.c
--- linux-2.6/drivers/ide/ide-dma.c 7 Aug 2003 07:35:12 -0000 1.60
+++ linux-2.6/drivers/ide/ide-dma.c 10 Aug 2003 08:40:52 -0000
@@ -255,7 +255,7 @@
#endif
memset(&sg[nents], 0, sizeof(*sg));
sg[nents].page = virt_to_page(virt_addr);
- sg[nents].offset = (unsigned long) virt_addr & ~PAGE_MASK;
+ sg[nents].offset = virt_to_pageoff(virt_addr);
sg[nents].length = 128 * SECTOR_SIZE;
nents++;
virt_addr = virt_addr + (128 * SECTOR_SIZE);
@@ -263,7 +263,7 @@
}
memset(&sg[nents], 0, sizeof(*sg));
sg[nents].page = virt_to_page(virt_addr);
- sg[nents].offset = (unsigned long) virt_addr & ~PAGE_MASK;
+ sg[nents].offset = virt_to_pageoff(virt_addr);
sg[nents].length = sector_count * SECTOR_SIZE;
nents++;

Index: linux-2.6/drivers/ide/arm/icside.c
===================================================================
RCS file: /home/cvs/linux-2.5/drivers/ide/arm/icside.c,v
retrieving revision 1.8
diff -u -r1.8 icside.c
--- linux-2.6/drivers/ide/arm/icside.c 19 May 2003 17:48:30 -0000 1.8
+++ linux-2.6/drivers/ide/arm/icside.c 10 Aug 2003 08:40:52 -0000
@@ -233,7 +233,7 @@

memset(sg, 0, sizeof(*sg));
sg->page = virt_to_page(rq->buffer);
- sg->offset = ((unsigned long)rq->buffer) & ~PAGE_MASK;
+ sg->offset = virt_to_pageoff(rq->buffer);
sg->length = rq->nr_sectors * SECTOR_SIZE;
nents = 1;
} else {
Index: linux-2.6/drivers/ide/ppc/pmac.c
===================================================================
RCS file: /home/cvs/linux-2.5/drivers/ide/ppc/pmac.c,v
retrieving revision 1.13
diff -u -r1.13 pmac.c
--- linux-2.6/drivers/ide/ppc/pmac.c 6 Jul 2003 19:33:43 -0000 1.13
+++ linux-2.6/drivers/ide/ppc/pmac.c 10 Aug 2003 08:40:52 -0000
@@ -971,7 +971,7 @@
if (sector_count > 127) {
memset(&sg[nents], 0, sizeof(*sg));
sg[nents].page = virt_to_page(virt_addr);
- sg[nents].offset = (unsigned long) virt_addr & ~PAGE_MASK;
+ sg[nents].offset = virt_to_pageoff(virt_addr);
sg[nents].length = 127 * SECTOR_SIZE;
nents++;
virt_addr = virt_addr + (127 * SECTOR_SIZE);
@@ -979,7 +979,7 @@
}
memset(&sg[nents], 0, sizeof(*sg));
sg[nents].page = virt_to_page(virt_addr);
- sg[nents].offset = (unsigned long) virt_addr & ~PAGE_MASK;
+ sg[nents].offset = virt_to_pageoff(virt_addr);
sg[nents].length = sector_count * SECTOR_SIZE;
nents++;

--
Hideaki YOSHIFUJI @ USAGI Project <yosh...@linux-ipv6.org>
GPG FP: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA

YOSHIFUJI Hideaki / 吉藤英明

unread,
Aug 10, 2003, 7:20:05 AM8/10/03
to
[4/9] convert drivers/block to virt_to_pageoff().

Index: linux-2.6/drivers/block/cryptoloop.c
===================================================================
RCS file: /home/cvs/linux-2.5/drivers/block/cryptoloop.c,v
retrieving revision 1.3
diff -u -r1.3 cryptoloop.c
--- linux-2.6/drivers/block/cryptoloop.c 17 Jul 2003 17:43:53 -0000 1.3
+++ linux-2.6/drivers/block/cryptoloop.c 10 Aug 2003 08:40:52 -0000
@@ -112,11 +112,11 @@
iv[0] = cpu_to_le32(IV & 0xffffffff);

sg_in.page = virt_to_page(in);
- sg_in.offset = (unsigned long)in & ~PAGE_MASK;
+ sg_in.offset = virt_to_pageoff(in);
sg_in.length = sz;

sg_out.page = virt_to_page(out);
- sg_out.offset = (unsigned long)out & ~PAGE_MASK;
+ sg_out.offset = virt_to_pageoff(out);
sg_out.length = sz;

encdecfunc(tfm, &sg_out, &sg_in, sz, (u8 *)iv);

--
Hideaki YOSHIFUJI @ USAGI Project <yosh...@linux-ipv6.org>
GPG FP: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA

YOSHIFUJI Hideaki / 吉藤英明

unread,
Aug 10, 2003, 7:20:08 AM8/10/03
to
[7/9] convert drivers/scsi to virt_to_pageoff().

Index: linux-2.6/drivers/scsi/3w-xxxx.c
===================================================================
RCS file: /home/cvs/linux-2.5/drivers/scsi/3w-xxxx.c,v
retrieving revision 1.34
diff -u -r1.34 3w-xxxx.c
--- linux-2.6/drivers/scsi/3w-xxxx.c 17 Jul 2003 17:43:53 -0000 1.34
+++ linux-2.6/drivers/scsi/3w-xxxx.c 10 Aug 2003 09:30:32 -0000
@@ -2112,7 +2112,7 @@
if (cmd->request_bufflen == 0)
return 0;

- mapping = pci_map_page(pdev, virt_to_page(cmd->request_buffer), ((unsigned long)cmd->request_buffer & ~PAGE_MASK), cmd->request_bufflen, dma_dir);
+ mapping = pci_map_page(pdev, virt_to_page(cmd->request_buffer), virt_to_pageoff(cmd->request_buffer), cmd->request_bufflen, dma_dir);

if (mapping == 0) {
printk(KERN_WARNING "3w-xxxx: tw_map_scsi_single_data(): pci_map_page() failed.\n");
Index: linux-2.6/drivers/scsi/ide-scsi.c
===================================================================
RCS file: /home/cvs/linux-2.5/drivers/scsi/ide-scsi.c,v
retrieving revision 1.80
diff -u -r1.80 ide-scsi.c
--- linux-2.6/drivers/scsi/ide-scsi.c 18 Jul 2003 20:29:54 -0000 1.80
+++ linux-2.6/drivers/scsi/ide-scsi.c 10 Aug 2003 09:30:32 -0000
@@ -761,8 +761,8 @@
printk ("ide-scsi: %s: building DMA table for a single buffer (%dkB)\n", drive->name, pc->request_transfer >> 10);
#endif /* IDESCSI_DEBUG_LOG */
bh->bi_io_vec[0].bv_page = virt_to_page(pc->scsi_cmd->request_buffer);
+ bh->bi_io_vec[0].bv_offset = virt_to_pageoff(pc->scsi_cmd->request_buffer);
bh->bi_io_vec[0].bv_len = pc->request_transfer;
- bh->bi_io_vec[0].bv_offset = (unsigned long) pc->scsi_cmd->request_buffer & ~PAGE_MASK;
bh->bi_size = pc->request_transfer;
}
return first_bh;
Index: linux-2.6/drivers/scsi/megaraid.c
===================================================================
RCS file: /home/cvs/linux-2.5/drivers/scsi/megaraid.c,v
retrieving revision 1.43
diff -u -r1.43 megaraid.c
--- linux-2.6/drivers/scsi/megaraid.c 17 Jul 2003 17:43:53 -0000 1.43
+++ linux-2.6/drivers/scsi/megaraid.c 10 Aug 2003 09:30:32 -0000
@@ -2275,8 +2275,7 @@
if( !cmd->use_sg ) {

page = virt_to_page(cmd->request_buffer);
-
- offset = ((unsigned long)cmd->request_buffer & ~PAGE_MASK);
+ offset = virt_to_pageoff(cmd->request_buffer);

scb->dma_h_bulkdata = pci_map_page(adapter->dev,
page, offset,
Index: linux-2.6/drivers/scsi/qlogicfc.c
===================================================================
RCS file: /home/cvs/linux-2.5/drivers/scsi/qlogicfc.c,v
retrieving revision 1.34
diff -u -r1.34 qlogicfc.c
--- linux-2.6/drivers/scsi/qlogicfc.c 17 Jul 2003 17:43:53 -0000 1.34
+++ linux-2.6/drivers/scsi/qlogicfc.c 10 Aug 2003 09:30:32 -0000
@@ -1283,8 +1283,7 @@
}
} else if (Cmnd->request_bufflen && Cmnd->sc_data_direction != PCI_DMA_NONE) {
struct page *page = virt_to_page(Cmnd->request_buffer);
- unsigned long offset = ((unsigned long)Cmnd->request_buffer &
- ~PAGE_MASK);
+ unsigned long offset = virt_to_pageoff(Cmnd->request_buffer);
dma_addr_t busaddr = pci_map_page(hostdata->pci_dev,
page, offset,
Cmnd->request_bufflen,
@@ -1927,8 +1926,7 @@
*/
busaddr = pci_map_page(hostdata->pci_dev,
virt_to_page(&hostdata->control_block),
- ((unsigned long) &hostdata->control_block &
- ~PAGE_MASK),
+ virt_to_pageoff(&hostdata->control_block),
sizeof(hostdata->control_block),
PCI_DMA_BIDIRECTIONAL);

Index: linux-2.6/drivers/scsi/sg.c
===================================================================
RCS file: /home/cvs/linux-2.5/drivers/scsi/sg.c,v
retrieving revision 1.54
diff -u -r1.54 sg.c
--- linux-2.6/drivers/scsi/sg.c 17 Jul 2003 17:43:53 -0000 1.54
+++ linux-2.6/drivers/scsi/sg.c 10 Aug 2003 09:30:33 -0000
@@ -1813,7 +1813,7 @@
break;
}
sclp->page = virt_to_page(p);
- sclp->offset = (unsigned long) p & ~PAGE_MASK;
+ sclp->offset = virt_to_pageoff(p);
sclp->length = ret_sz;

SCSI_LOG_TIMEOUT(5, printk("sg_build_build: k=%d, a=0x%p, len=%d\n",
Index: linux-2.6/drivers/scsi/sym53c8xx.c
===================================================================
RCS file: /home/cvs/linux-2.5/drivers/scsi/sym53c8xx.c,v
retrieving revision 1.39
diff -u -r1.39 sym53c8xx.c
--- linux-2.6/drivers/scsi/sym53c8xx.c 18 Jul 2003 16:56:15 -0000 1.39
+++ linux-2.6/drivers/scsi/sym53c8xx.c 10 Aug 2003 09:30:33 -0000
@@ -1162,8 +1162,7 @@

mapping = pci_map_page(pdev,
virt_to_page(cmd->request_buffer),
- ((unsigned long)cmd->request_buffer &
- ~PAGE_MASK),
+ virt_to_pageoff(cmd->request_buffer),
cmd->request_bufflen, dma_dir);
__data_mapped(cmd) = 1;
__data_mapping(cmd) = mapping;
Index: linux-2.6/drivers/scsi/arm/scsi.h
===================================================================
RCS file: /home/cvs/linux-2.5/drivers/scsi/arm/scsi.h,v
retrieving revision 1.2
diff -u -r1.2 scsi.h
--- linux-2.6/drivers/scsi/arm/scsi.h 19 May 2003 17:48:30 -0000 1.2
+++ linux-2.6/drivers/scsi/arm/scsi.h 10 Aug 2003 09:30:33 -0000
@@ -23,7 +23,7 @@
BUG_ON(bufs + 1 > max);

sg->page = virt_to_page(SCp->ptr);
- sg->offset = ((unsigned int)SCp->ptr) & ~PAGE_MASK;
+ sg->offset = virt_to_pageoff(SCp->ptr);
sg->length = SCp->this_residual;

if (bufs)

--
Hideaki YOSHIFUJI @ USAGI Project <yosh...@linux-ipv6.org>
GPG FP: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA

YOSHIFUJI Hideaki / 吉藤英明

unread,
Aug 10, 2003, 7:20:06 AM8/10/03
to
[6/9] convert drivers/net to virt_to_pageoff().

Index: linux-2.6/drivers/net/acenic.c
===================================================================
RCS file: /home/cvs/linux-2.5/drivers/net/acenic.c,v
retrieving revision 1.36
diff -u -r1.36 acenic.c
--- linux-2.6/drivers/net/acenic.c 1 Aug 2003 22:07:01 -0000 1.36
+++ linux-2.6/drivers/net/acenic.c 10 Aug 2003 08:40:52 -0000
@@ -1960,7 +1960,7 @@
*/
skb_reserve(skb, 2 + 16);
mapping = pci_map_page(ap->pdev, virt_to_page(skb->data),
- ((unsigned long)skb->data & ~PAGE_MASK),
+ virt_to_pageoff(skb->data),
ACE_STD_BUFSIZE - (2 + 16),
PCI_DMA_FROMDEVICE);
ap->skb->rx_std_skbuff[idx].skb = skb;
@@ -2026,7 +2026,7 @@
*/
skb_reserve(skb, 2 + 16);
mapping = pci_map_page(ap->pdev, virt_to_page(skb->data),
- ((unsigned long)skb->data & ~PAGE_MASK),
+ virt_to_pageoff(skb->data),
ACE_MINI_BUFSIZE - (2 + 16),
PCI_DMA_FROMDEVICE);
ap->skb->rx_mini_skbuff[idx].skb = skb;
@@ -2087,7 +2087,7 @@
*/
skb_reserve(skb, 2 + 16);
mapping = pci_map_page(ap->pdev, virt_to_page(skb->data),
- ((unsigned long)skb->data & ~PAGE_MASK),
+ virt_to_pageoff(skb->data),
ACE_JUMBO_BUFSIZE - (2 + 16),
PCI_DMA_FROMDEVICE);
ap->skb->rx_jumbo_skbuff[idx].skb = skb;
@@ -2743,7 +2743,7 @@
struct tx_ring_info *info;

mapping = pci_map_page(ap->pdev, virt_to_page(skb->data),
- ((unsigned long) skb->data & ~PAGE_MASK),
+ virt_to_pageoff(skb->data),
skb->len, PCI_DMA_TODEVICE);

info = ap->skb->tx_skbuff + idx;
Index: linux-2.6/drivers/net/sungem.c
===================================================================
RCS file: /home/cvs/linux-2.5/drivers/net/sungem.c,v
retrieving revision 1.40
diff -u -r1.40 sungem.c
--- linux-2.6/drivers/net/sungem.c 3 Aug 2003 18:34:10 -0000 1.40
+++ linux-2.6/drivers/net/sungem.c 10 Aug 2003 08:40:53 -0000
@@ -725,8 +725,7 @@
skb_put(new_skb, (ETH_FRAME_LEN + RX_OFFSET));
rxd->buffer = cpu_to_le64(pci_map_page(gp->pdev,
virt_to_page(new_skb->data),
- ((unsigned long) new_skb->data &
- ~PAGE_MASK),
+ virt_to_pageoff(new_skb->data),
RX_BUF_ALLOC_SIZE(gp),
PCI_DMA_FROMDEVICE));
skb_reserve(new_skb, RX_OFFSET);
@@ -873,8 +872,7 @@
len = skb->len;
mapping = pci_map_page(gp->pdev,
virt_to_page(skb->data),
- ((unsigned long) skb->data &
- ~PAGE_MASK),
+ virt_to_pageoff(skb->data),
len, PCI_DMA_TODEVICE);
ctrl |= TXDCTRL_SOF | TXDCTRL_EOF | len;
if (gem_intme(entry))
@@ -898,7 +896,7 @@
*/
first_len = skb_headlen(skb);
first_mapping = pci_map_page(gp->pdev, virt_to_page(skb->data),
- ((unsigned long) skb->data & ~PAGE_MASK),
+ virt_to_pageoff(skb->data),
first_len, PCI_DMA_TODEVICE);
entry = NEXT_TX(entry);

@@ -1464,8 +1462,7 @@
skb_put(skb, (ETH_FRAME_LEN + RX_OFFSET));
dma_addr = pci_map_page(gp->pdev,
virt_to_page(skb->data),
- ((unsigned long) skb->data &
- ~PAGE_MASK),
+ virt_to_pageoff(skb->data),
RX_BUF_ALLOC_SIZE(gp),
PCI_DMA_FROMDEVICE);
rxd->buffer = cpu_to_le64(dma_addr);
Index: linux-2.6/drivers/net/sk98lin/skge.c
===================================================================
RCS file: /home/cvs/linux-2.5/drivers/net/sk98lin/skge.c,v
retrieving revision 1.24
diff -u -r1.24 skge.c
--- linux-2.6/drivers/net/sk98lin/skge.c 1 Aug 2003 19:02:34 -0000 1.24
+++ linux-2.6/drivers/net/sk98lin/skge.c 10 Aug 2003 08:40:53 -0000
@@ -2142,7 +2142,7 @@
*/
PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
virt_to_page(pMessage->data),
- ((unsigned long) pMessage->data & ~PAGE_MASK),
+ virt_to_pageoff(pMessage->data),
pMessage->len,
PCI_DMA_TODEVICE);
pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff);
@@ -2259,7 +2259,7 @@
*/
PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
virt_to_page(pMessage->data),
- ((unsigned long) pMessage->data & ~PAGE_MASK),
+ virt_to_pageoff(pMessage->data),
skb_headlen(pMessage),
PCI_DMA_TODEVICE);

@@ -2518,8 +2518,7 @@
Length = pAC->RxBufSize;
PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
virt_to_page(pMsgBlock->data),
- ((unsigned long) pMsgBlock->data &
- ~PAGE_MASK),
+ virt_to_pageoff(pMsgBlock->data),
pAC->RxBufSize - 2,
PCI_DMA_FROMDEVICE);

--
Hideaki YOSHIFUJI @ USAGI Project <yosh...@linux-ipv6.org>
GPG FP: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA

YOSHIFUJI Hideaki / 吉藤英明

unread,
Aug 10, 2003, 7:20:08 AM8/10/03
to
[9/9] convert fs/jbd to virt_to_pageoff().

Index: linux-2.6/fs/jbd/journal.c
===================================================================
RCS file: /home/cvs/linux-2.5/fs/jbd/journal.c,v
retrieving revision 1.62
diff -u -r1.62 journal.c
--- linux-2.6/fs/jbd/journal.c 11 Jul 2003 07:04:11 -0000 1.62
+++ linux-2.6/fs/jbd/journal.c 10 Aug 2003 08:40:54 -0000
@@ -278,9 +278,6 @@
* Bit 1 set == buffer copy-out performed (kfree the data after IO)
*/

-static inline unsigned long virt_to_offset(void *p)
-{return ((unsigned long) p) & ~PAGE_MASK;}
-
int journal_write_metadata_buffer(transaction_t *transaction,
struct journal_head *jh_in,
struct journal_head **jh_out,
@@ -318,10 +315,10 @@
if (jh_in->b_frozen_data) {
done_copy_out = 1;
new_page = virt_to_page(jh_in->b_frozen_data);
- new_offset = virt_to_offset(jh_in->b_frozen_data);
+ new_offset = virt_to_pageoff(jh_in->b_frozen_data);
} else {
new_page = jh2bh(jh_in)->b_page;
- new_offset = virt_to_offset(jh2bh(jh_in)->b_data);
+ new_offset = virt_to_pageoff(jh2bh(jh_in)->b_data);
}

mapped_data = kmap_atomic(new_page, KM_USER0);
@@ -358,7 +355,7 @@
address kmapped so that we can clear the escaped
magic number below. */
new_page = virt_to_page(tmp);
- new_offset = virt_to_offset(tmp);
+ new_offset = virt_to_pageoff(tmp);
done_copy_out = 1;
}

--
Hideaki YOSHIFUJI @ USAGI Project <yosh...@linux-ipv6.org>
GPG FP: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA

YOSHIFUJI Hideaki / 吉藤英明

unread,
Aug 10, 2003, 7:20:10 AM8/10/03
to
[8/9] convert drivers/usb to virt_to_pageoff().

Index: linux-2.6/drivers/usb/misc/usbtest.c
===================================================================
RCS file: /home/cvs/linux-2.5/drivers/usb/misc/usbtest.c,v
retrieving revision 1.19
diff -u -r1.19 usbtest.c
--- linux-2.6/drivers/usb/misc/usbtest.c 1 Aug 2003 18:12:47 -0000 1.19
+++ linux-2.6/drivers/usb/misc/usbtest.c 10 Aug 2003 08:40:53 -0000
@@ -271,7 +271,7 @@

/* kmalloc pages are always physically contiguous! */
sg [i].page = virt_to_page (buf);
- sg [i].offset = ((unsigned) buf) & ~PAGE_MASK;
+ sg [i].offset = virt_to_pageoff (buf);
sg [i].length = size;

if (vary) {
Index: linux-2.6/drivers/usb/storage/sddr09.c
===================================================================
RCS file: /home/cvs/linux-2.5/drivers/usb/storage/sddr09.c,v
retrieving revision 1.23
diff -u -r1.23 sddr09.c
--- linux-2.6/drivers/usb/storage/sddr09.c 17 Jul 2003 22:58:33 -0000 1.23
+++ linux-2.6/drivers/usb/storage/sddr09.c 10 Aug 2003 08:40:54 -0000
@@ -1127,7 +1127,7 @@
char *vaddr = kmalloc(alloc_req, GFP_NOIO);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,3)
sg[i].page = virt_to_page(vaddr);
- sg[i].offset = ((unsigned long)vaddr & ~PAGE_MASK);
+ sg[i].offset = virt_to_pageoff(vaddr);
#else
sg[i].address = vaddr;
#endif

--
Hideaki YOSHIFUJI @ USAGI Project <yosh...@linux-ipv6.org>
GPG FP: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA

Christoph Hellwig

unread,
Aug 10, 2003, 7:40:07 AM8/10/03
to
On Sun, Aug 10, 2003 at 08:10:09PM +0900, YOSHIFUJI Hideaki / ?$B5HF#1QL@?(B wrote:
> [7/9] convert drivers/scsi to virt_to_pageoff().
>
> Index: linux-2.6/drivers/scsi/3w-xxxx.c
> ===================================================================
> RCS file: /home/cvs/linux-2.5/drivers/scsi/3w-xxxx.c,v
> retrieving revision 1.34
> diff -u -r1.34 3w-xxxx.c
> --- linux-2.6/drivers/scsi/3w-xxxx.c 17 Jul 2003 17:43:53 -0000 1.34
> +++ linux-2.6/drivers/scsi/3w-xxxx.c 10 Aug 2003 09:30:32 -0000
> @@ -2112,7 +2112,7 @@
> if (cmd->request_bufflen == 0)
> return 0;
>
> - mapping = pci_map_page(pdev, virt_to_page(cmd->request_buffer), ((unsigned long)cmd->request_buffer & ~PAGE_MASK), cmd->request_bufflen, dma_dir);
> + mapping = pci_map_page(pdev, virt_to_page(cmd->request_buffer), virt_to_pageoff(cmd->request_buffer), cmd->request_bufflen, dma_dir);

You probably want to use pci_map_single here instead..

> --- linux-2.6/drivers/scsi/megaraid.c 17 Jul 2003 17:43:53 -0000 1.43
> +++ linux-2.6/drivers/scsi/megaraid.c 10 Aug 2003 09:30:32 -0000
> @@ -2275,8 +2275,7 @@
> if( !cmd->use_sg ) {
>
> page = virt_to_page(cmd->request_buffer);
> -
> - offset = ((unsigned long)cmd->request_buffer & ~PAGE_MASK);
> + offset = virt_to_pageoff(cmd->request_buffer);

Dito.

> --- linux-2.6/drivers/scsi/qlogicfc.c 17 Jul 2003 17:43:53 -0000 1.34
> +++ linux-2.6/drivers/scsi/qlogicfc.c 10 Aug 2003 09:30:32 -0000
> @@ -1283,8 +1283,7 @@
> }
> } else if (Cmnd->request_bufflen && Cmnd->sc_data_direction != PCI_DMA_NONE) {
> struct page *page = virt_to_page(Cmnd->request_buffer);
> - unsigned long offset = ((unsigned long)Cmnd->request_buffer &
> - ~PAGE_MASK);
> + unsigned long offset = virt_to_pageoff(Cmnd->request_buffer);
> dma_addr_t busaddr = pci_map_page(hostdata->pci_dev,
> page, offset,
> Cmnd->request_bufflen,

Dito.

> @@ -1927,8 +1926,7 @@
> */
> busaddr = pci_map_page(hostdata->pci_dev,
> virt_to_page(&hostdata->control_block),
> - ((unsigned long) &hostdata->control_block &
> - ~PAGE_MASK),
> + virt_to_pageoff(&hostdata->control_block),
> sizeof(hostdata->control_block),
> PCI_DMA_BIDIRECTIONAL);

Dito.

> --- linux-2.6/drivers/scsi/sym53c8xx.c 18 Jul 2003 16:56:15 -0000 1.39
> +++ linux-2.6/drivers/scsi/sym53c8xx.c 10 Aug 2003 09:30:33 -0000
> @@ -1162,8 +1162,7 @@
>
> mapping = pci_map_page(pdev,
> virt_to_page(cmd->request_buffer),
> - ((unsigned long)cmd->request_buffer &
> - ~PAGE_MASK),
> + virt_to_pageoff(cmd->request_buffer),

Dito.

> --- linux-2.6/drivers/scsi/arm/scsi.h 19 May 2003 17:48:30 -0000 1.2
> +++ linux-2.6/drivers/scsi/arm/scsi.h 10 Aug 2003 09:30:33 -0000
> @@ -23,7 +23,7 @@
> BUG_ON(bufs + 1 > max);
>
> sg->page = virt_to_page(SCp->ptr);
> - sg->offset = ((unsigned int)SCp->ptr) & ~PAGE_MASK;
> + sg->offset = virt_to_pageoff(SCp->ptr);
> sg->length = SCp->this_residual;

Dito.

David S. Miller

unread,
Aug 10, 2003, 8:00:13 AM8/10/03
to
On Sun, 10 Aug 2003 12:31:48 +0100
Christoph Hellwig <h...@infradead.org> wrote:

> You probably want to use pci_map_single here instead..

I don't think it's wise to mix two changes at once. Let's get
the straightforward "obvious" shorthand change in, then we can
add your enhancement.

YOSHIFUJI Hideaki / 吉藤英明

unread,
Aug 10, 2003, 8:10:06 AM8/10/03
to
In article <20030810045121...@redhat.com> (at Sun, 10 Aug 2003 04:51:21 -0700), "David S. Miller" <da...@redhat.com> says:

> On Sun, 10 Aug 2003 12:31:48 +0100
> Christoph Hellwig <h...@infradead.org> wrote:
>
> > You probably want to use pci_map_single here instead..
>
> I don't think it's wise to mix two changes at once. Let's get
> the straightforward "obvious" shorthand change in, then we can
> add your enhancement.

Agreed.

BTW, drivers/scsi/3w-xxxx.c says:

1.02.00.029 - Add missing pci_free_consistent() in tw_allocate_memory().
Replace pci_map_single() with pci_map_page() for highmem.
Check for tw_setfeature() failure.

Have problems in pci_map_single() with highmem already gone away?

--
Hideaki YOSHIFUJI @ USAGI Project <yosh...@linux-ipv6.org>
GPG FP: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA

James Morris

unread,
Aug 10, 2003, 9:30:09 AM8/10/03
to
On Sat, 9 Aug 2003, Matt Mackall wrote:

> out. Another thing I failed to mention at 3am is that most of the
> speed increase actually comes from the following patch which wasn't in
> baseline and isn't cryptoapi-specific. So I expect the cryptoapi
> version is about 30% faster once you amortize the initialization
> stuff.
>
> >>>>
> Remove folding step and double throughput.

Why did you remove this?


- James
--
James Morris
<jmo...@intercode.com.au>

Russell King

unread,
Aug 10, 2003, 10:00:09 AM8/10/03
to
On Sun, Aug 10, 2003 at 12:31:48PM +0100, Christoph Hellwig wrote:
> > --- linux-2.6/drivers/scsi/arm/scsi.h 19 May 2003 17:48:30 -0000 1.2
> > +++ linux-2.6/drivers/scsi/arm/scsi.h 10 Aug 2003 09:30:33 -0000
> > @@ -23,7 +23,7 @@
> > BUG_ON(bufs + 1 > max);
> >
> > sg->page = virt_to_page(SCp->ptr);
> > - sg->offset = ((unsigned int)SCp->ptr) & ~PAGE_MASK;
> > + sg->offset = virt_to_pageoff(SCp->ptr);
> > sg->length = SCp->this_residual;
>
> Dito.

No. DMA mapping is handled later.

--
Russell King (r...@arm.linux.org.uk) The developer of ARM Linux
http://www.arm.linux.org.uk/personal/aboutme.html

Russell King

unread,
Aug 10, 2003, 10:00:10 AM8/10/03
to
On Sun, Aug 10, 2003 at 12:31:48PM +0100, Christoph Hellwig wrote:
> > --- linux-2.6/drivers/scsi/arm/scsi.h 19 May 2003 17:48:30 -0000 1.2
> > +++ linux-2.6/drivers/scsi/arm/scsi.h 10 Aug 2003 09:30:33 -0000
> > @@ -23,7 +23,7 @@
> > BUG_ON(bufs + 1 > max);
> >
> > sg->page = virt_to_page(SCp->ptr);
> > - sg->offset = ((unsigned int)SCp->ptr) & ~PAGE_MASK;
> > + sg->offset = virt_to_pageoff(SCp->ptr);
> > sg->length = SCp->this_residual;
>
> Dito.

Actually, I'd rather see Scsi_Pointer gain page + offset (or even better
a single sg element) and get rid of these conversions.

-

James Morris

unread,
Aug 10, 2003, 11:00:06 AM8/10/03
to
On Sat, 9 Aug 2003, David S. Miller wrote:

> > Also, I posted to cryptoapi-devel that I need a way to disable the
> > unconditional padding on the hash functions.
>
> James, comments?

Yes, a flag could be added for crypto_alloc_tfm() which disables padding
for digests (e.g. CRYPTO_TFM_DIGEST_NOPAD).

Given that there are a still a number of unresolved issues, e.g. making
the crypto api (or a subset thereof) mandatory, perhaps it would be more
appropriate to slate these changes for 2.7 and then backport to 2.6 once
stable.


- James
--
James Morris
<jmo...@intercode.com.au>

Christoph Hellwig

unread,
Aug 10, 2003, 11:00:15 AM8/10/03
to
On Sun, Aug 10, 2003 at 09:03:22PM +0900, YOSHIFUJI Hideaki / ?$B5HF#1QL@?(B wrote:
> BTW, drivers/scsi/3w-xxxx.c says:
>
> 1.02.00.029 - Add missing pci_free_consistent() in tw_allocate_memory().
> Replace pci_map_single() with pci_map_page() for highmem.
> Check for tw_setfeature() failure.
>
> Have problems in pci_map_single() with highmem already gone away?

pci_map_single can't support highmem, but the case you converted can't
be highmem either. There's other places in the driver where we get handed
scatterlists that can contain highmem pages and thus need to be handled
with pci_map_page or better with pci_map_sg.

Christoph Hellwig

unread,
Aug 10, 2003, 11:00:15 AM8/10/03
to
On Sun, Aug 10, 2003 at 02:55:11PM +0100, Russell King wrote:
> Actually, I'd rather see Scsi_Pointer gain page + offset (or even better
> a single sg element) and get rid of these conversions.

Patches are welcome...

Christoph Hellwig

unread,
Aug 10, 2003, 11:00:14 AM8/10/03
to
On Sun, Aug 10, 2003 at 04:51:21AM -0700, David S. Miller wrote:
> On Sun, 10 Aug 2003 12:31:48 +0100
> Christoph Hellwig <h...@infradead.org> wrote:
>
> > You probably want to use pci_map_single here instead..
>
> I don't think it's wise to mix two changes at once. Let's get
> the straightforward "obvious" shorthand change in, then we can
> add your enhancement.

Ok.

Matt Mackall

unread,
Aug 10, 2003, 1:50:08 PM8/10/03
to
On Sun, Aug 10, 2003 at 11:18:43PM +1000, James Morris wrote:
> On Sat, 9 Aug 2003, Matt Mackall wrote:
>
> > out. Another thing I failed to mention at 3am is that most of the
> > speed increase actually comes from the following patch which wasn't in
> > baseline and isn't cryptoapi-specific. So I expect the cryptoapi
> > version is about 30% faster once you amortize the initialization
> > stuff.
> >
> > >>>>
> > Remove folding step and double throughput.
>
> Why did you remove this?

I suppose the comment you deleted was a little light on details, sigh.

The idea with the folding was that we can cover up any systemic
patterns in the returned hash by xoring the first half of the hash
with the second half of the hash. While this might seem like a good
technique intuitively, it's mathematically flawed.

Let's assume the simplest case of a two bit hash xy. "Patterns" here
are going to translate into a correlation between otherwise
well-distributed x and y. A perfectly uncorrelated system xy is going
to have two bits of entropy. A perfectly correlated (or
anti-correlated) system xy is going to have only 1 bit of entropy.

Now what happens when we fold these two bits together z=x^y? In the
uncorrelated case we end up with a well-distributed z. In the
correlated case, we end up with 0 or 1, that is z=x^x=0 or z=x^-x, and
we've eliminated any entropy we once had. If correlation is less than
100%, then we get somewhere between 0 and 1 bits of entropy, but
always less than if we just returned z=x or z=y. This argument
naturally scales up to larger variables x and y.

Ok, so that explains taking out the xor. But I also return xy and not
just x. With the former, every bit of input goes through SHA1 twice,
once in the input pool, and once in the output pool, along with lots
of feedback to foil backtracking attacks. In the latter, every output
bit is going through SHA four times, which is just overkill. If we
don't trust our hash to generate uniform, non-self-correlating output,
running additional rounds does not guarantee that we aren't magnifying
the problem. And it is of course making everything twice as expensive.

--
Matt Mackall : http://www.selenic.com : of or relating to the moon

Jamie Lokier

unread,
Aug 10, 2003, 10:20:05 PM8/10/03
to
[Ted T'so added to recipients because he wrote this thing :)]

If you return xy, you are returning a strong digest of the pool state.
Even with the backtrack-prevention, if the attacker reads 20 bytes
from /dev/random and sees a _recognised_ pattern, they immediately
know the entire state of the secondary pool.

This can happen if, for example, a machine has just rebooted and
hasn't had time to collect much entropy since the initial state.

(In general, recognising the output of a cryptographic hash tells you
the input, because even though there are many possible inputs for that
output, it's far more likely that a systemic error is the cause of the
recognised output, rather than the cause being randomness).

This means that, for a short time after, they can predict further
output bits exactly. "Catastrophic reseeding" from the primary pool
limits how many bits they can predict like this - unless, if they're
lucky, it tells them the state of the primary pool too.

When you output less of the hash, this reduces the information
available to predict the state of the pool. However, SHA1 is large
enough that even half of the hash is a strong predictor, so returning
half of the hash still has this weakness.

(Ironically, a much weaker hash would prevent this mode of data leakage).

As far as I can tell, folding the hash result doesn't help, because
that simply creates a different kind of hash which can also be
recognised, and which is large enough to predict the pool state.

Which leaves...

I have just convinced myself of a flaw in the existing random.c -
which still holds in your patched version. Folding the result of the
strong hash is useless. Instead, the _input_ to the strong hash
should be folded, so that a single hash result (whether folded or not)
doesn't reveal the pool state even when it is recognised.

In other words, the hash should be calculated over fewer than all of
the pool bits each time. The set of pool bits used, or how multiple
bits are folded, needs to be varied in such a way that many hash
results would need to be all recognised to determine the pool state.

I think this equivalent to saying that the effective hash function
needs to be weak enough not to reveal the pool state when it is
recognised, due to the pool state being recognisably "special"
(e.g. limited time after booting), while at the same time the hash
needs to be strong enough that it does not reveal the pool state when
the pool is random.

Enjoy,
-- Jamie

Jamie Lokier

unread,
Aug 10, 2003, 10:20:10 PM8/10/03
to
Matt Mackall wrote:
> > > Ok, can I export some more cryptoapi primitives?

Why so complicated? Just move the "sha1_transform" function to its
own file in lib, and call it from both drivers/char/random.c and
crypto/sha1.c.

Problem solved.

Matt Mackall

unread,
Aug 10, 2003, 10:50:07 PM8/10/03
to
On Mon, Aug 11, 2003 at 03:15:12AM +0100, Jamie Lokier wrote:
> Matt Mackall wrote:
> > > > Ok, can I export some more cryptoapi primitives?
>
> Why so complicated? Just move the "sha1_transform" function to its
> own file in lib, and call it from both drivers/char/random.c and
> crypto/sha1.c.
>
> Problem solved.

Because I can't eventually put random=sha384,aes and on the command line
and get hardware acceleration.

--
Matt Mackall : http://www.selenic.com : of or relating to the moon

Matt Mackall

unread,
Aug 10, 2003, 10:50:07 PM8/10/03
to

Except we're only ever hashing part of the pool.

> This can happen if, for example, a machine has just rebooted and
> hasn't had time to collect much entropy since the initial state.

In this case /dev/random simply won't generate output. Of course
/dev/urandom has an issue here, which is why it's always been recommended
practice to reseed the pool at boot as well.

> (In general, recognising the output of a cryptographic hash tells you
> the input, because even though there are many possible inputs for that
> output, it's far more likely that a systemic error is the cause of the
> recognised output, rather than the cause being randomness).

This is just as true of the folded 80 bits as it is of the full 160,
of course.


> This means that, for a short time after, they can predict further
> output bits exactly. "Catastrophic reseeding" from the primary pool
> limits how many bits they can predict like this - unless, if they're
> lucky, it tells them the state of the primary pool too.

That limit is currently 64 bits and in practice is probably zero
because we've just pulled more entropy from the input pool so we
actually can't guess the other half of the output pool even if have
scored a hash hit.

> When you output less of the hash, this reduces the information
> available to predict the state of the pool. However, SHA1 is large
> enough that even half of the hash is a strong predictor, so returning
> half of the hash still has this weakness.
>
> (Ironically, a much weaker hash would prevent this mode of data leakage).

Yes, the ideal implementation is to use a regular 1:1 block cipher
here. I've been looking at doing that for the output pool(s).



> As far as I can tell, folding the hash result doesn't help, because
> that simply creates a different kind of hash which can also be
> recognised, and which is large enough to predict the pool state.
>
> Which leaves...
>
> I have just convinced myself of a flaw in the existing random.c -
> which still holds in your patched version. Folding the result of the
> strong hash is useless. Instead, the _input_ to the strong hash
> should be folded, so that a single hash result (whether folded or not)
> doesn't reveal the pool state even when it is recognised.

Actually, "folding" it is the opposite of what you're looking for:

> In other words, the hash should be calculated over fewer than all of
> the pool bits each time. The set of pool bits used, or how multiple
> bits are folded, needs to be varied in such a way that many hash
> results would need to be all recognised to determine the pool state.

And we're safe here. The default pool size is 1024 bits, of which we
hash 512. I could hash even fewer, say, 480 (and this would deal with the
cryptoapi padding stuff nicely).

> I think this equivalent to saying that the effective hash function
> needs to be weak enough not to reveal the pool state when it is
> recognised, due to the pool state being recognisably "special"
> (e.g. limited time after booting), while at the same time the hash
> needs to be strong enough that it does not reveal the pool state when
> the pool is random.
>
> Enjoy,

--

Matt Mackall : http://www.selenic.com : of or relating to the moon

David Wagner

unread,
Aug 11, 2003, 1:10:04 AM8/11/03
to
Jamie Lokier wrote:
>If you return xy, you are returning a strong digest of the pool state.
>Even with the backtrack-prevention, if the attacker reads 20 bytes
>from /dev/random and sees a _recognised_ pattern, they immediately
>know the entire state of the secondary pool.

Irrelevant. I think you missed something.

If you pick a pattern in advance, the chance that your pattern appears
at the output of SHA1 is about 2^-160 (assuming SHA1 is secure). If you
pick 2^50 patterns (that takes an awfully big RAID array to store them
all!), then the chance that your pattent appears at the output of SHA1
is 2^-110. If you pick 2^50 patterns and poll /dev/urandom 2^50 times
to get 2^50 outputs, the chance that one of your patterns appears as one
of the /dev/urandom outputs is only 2^-60. In other words, your attack
has a success probability that is truly negligible.

You might as well argue that "if a cosmic ray hits memory and turns off
/dev/urandom, then things will fail". This is such an unlikely event
that we all ignore it. Likewise, the risk of special patterns appearing
at the output of SHA1 is also so unlikely that it can also be ignored.

Jamie Lokier

unread,
Aug 11, 2003, 1:10:07 AM8/11/03
to
Matt Mackall wrote:
> And we're safe here. The default pool size is 1024 bits, of which we
> hash 512. I could hash even fewer, say, 480 (and this would deal with the
> cryptoapi padding stuff nicely).

Where is the pool size set to 1024 bits? I'm reading 2.5.75, and it
looks to me like the hash is over the whole pool, of 512 bits for the
primary and 128 bits for the secondary pool:

for (i = 0, x = 0; i < r->poolinfo.poolwords; i += 16, x+=2) {
HASH_TRANSFORM(tmp, r->pool+i);
add_entropy_words(r, &tmp[x%HASH_BUFFER_SIZE], 1);
}

-- Jamie

David S. Miller

unread,
Aug 11, 2003, 1:10:08 AM8/11/03
to
On Mon, 11 Aug 2003 03:15:12 +0100
Jamie Lokier <ja...@shareable.org> wrote:

> Matt Mackall wrote:
> > > > Ok, can I export some more cryptoapi primitives?
>
> Why so complicated? Just move the "sha1_transform" function to its
> own file in lib, and call it from both drivers/char/random.c and
> crypto/sha1.c.

This is also broken.

The whole point of the 'tfm' the Crypto API makes you allocate is
that it provides all of the state and configuration information
needed to do the transforms.

There is no reason why random.c's usage of the crypto-API cannot be
done cleanly and efficiently such that it is both faster and resulting
in smaller code size than what random.c uses now. All of this _WITHOUT_
bypassing and compromising the well designed crypto API interfaces to these
transformations.

Matt Mackall

unread,
Aug 11, 2003, 1:10:10 AM8/11/03
to
On Mon, Aug 11, 2003 at 05:59:47AM +0100, Jamie Lokier wrote:
> Matt Mackall wrote:
> > And we're safe here. The default pool size is 1024 bits, of which we
> > hash 512. I could hash even fewer, say, 480 (and this would deal with the
> > cryptoapi padding stuff nicely).
>
> Where is the pool size set to 1024 bits? I'm reading 2.5.75, and it
> looks to me like the hash is over the whole pool, of 512 bits for the
> primary and 128 bits for the secondary pool:
>
> for (i = 0, x = 0; i < r->poolinfo.poolwords; i += 16, x+=2) {
^^^^

Unfortunately, there's an ugly mix of words, bytes, and bits here (and it
was actually broken for years because of it). The input pool is 4kbits
and the output pools are 1k.

--
Matt Mackall : http://www.selenic.com : of or relating to the moon

Jamie Lokier

unread,
Aug 11, 2003, 1:20:07 AM8/11/03
to
David S. Miller wrote:
> > Why so complicated? Just move the "sha1_transform" function to its
> > own file in lib, and call it from both drivers/char/random.c and
> > crypto/sha1.c.
>
> This is also broken.

Not wanted, perhaps, but there is nothing broken about it.

> The whole point of the 'tfm' the Crypto API makes you allocate is
> that it provides all of the state and configuration information
> needed to do the transforms.

That'll be the array of 5 u32s, then.

> There is no reason why random.c's usage of the crypto-API cannot be
> done cleanly and efficiently such that it is both faster and resulting
> in smaller code size than what random.c uses now.

I don't disagree that Crypto API is flexible, possibly desirable for
being able to change which algorithm random.c uses, and using it will
certainly remove a lot of lines from random.c.

But the registration and lookup part just so random.c can ultimately
call sha1_transform with its well known 5-word state and 16-word data
input can't possibly be as small as calling sha1_transform directly.

> All of this _WITHOUT_ bypassing and compromising the well designed
> crypto API interfaces to these transformations.

I don't believe you'll get "all of this", i.e. the smaller code size.

The state for sha1_transform is an array of 5 u32s, that's all. Going
via Crypto API is just a complicated way to call it in this case.

random.c does not use it in the conventional way, as a hash over an
arbitrary number of bytes, so that part of CryptoAPI is not relevant.
random.c also uses the intermediate states of the hash, to feed them
back into the pool.

I shall be very surprised if the supposed hardware acceleration can
make random.c faster with its current algorithm, because it operates
on such small chunks or data (16 bytes at a time - more I/O overhead
than crypto time, with hardware). A change of algorithm might do it though.

I shall be even more surprised if calling sha1_transform through
CryptoAPI results in a smaller kernel than what is done now (without
CryptoAPI linked in).

-- Jamie

Jamie Lokier

unread,
Aug 11, 2003, 1:30:09 AM8/11/03
to
Matt Mackall wrote:
> On Mon, Aug 11, 2003 at 05:59:47AM +0100, Jamie Lokier wrote:
> > Matt Mackall wrote:
> > > And we're safe here. The default pool size is 1024 bits, of which we
> > > hash 512. I could hash even fewer, say, 480 (and this would deal with the
> > > cryptoapi padding stuff nicely).
> >
> > Where is the pool size set to 1024 bits? I'm reading 2.5.75, and it
> > looks to me like the hash is over the whole pool, of 512 bits for the
> > primary and 128 bits for the secondary pool:
> >
> > for (i = 0, x = 0; i < r->poolinfo.poolwords; i += 16, x+=2) {
> ^^^^
>
> Unfortunately, there's an ugly mix of words, bytes, and bits here (and it
> was actually broken for years because of it). The input pool is 4kbits
> and the output pools are 1k.

You're right about the sizes. But you said it hashes only half of the
pool. Where is that?

-- Jamie

David S. Miller

unread,
Aug 11, 2003, 1:30:11 AM8/11/03