[PATCH V2 2/2] Remove VLAIS usage from crypto/testmgr.c

2012-10-31 Thread Behan Webster
From: Jan-Simon Möller 

The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This patch instead allocates the appropriate amount of memory
using an char array.

Patch from series at
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120507/142707.html
by PaX Team.

Signed-off-by: Jan-Simon Möller 
Cc: pagee...@freemail.hu
[Use shash_desc_ctx() to calculate address of ctx]
Signed-off-by: Behan Webster 
---
 crypto/testmgr.c |   17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 941d75c..8738ff4 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -1578,16 +1578,17 @@ static int alg_test_crc32c(const struct alg_test_desc 
*desc,
}
 
do {
-   struct {
-   struct shash_desc shash;
-   char ctx[crypto_shash_descsize(tfm)];
-   } sdesc;
+   char sdesc[sizeof(struct shash_desc)
+   + crypto_shash_descsize(tfm)
+   + CRYPTO_MINALIGN] CRYPTO_MINALIGN_ATTR;
+   struct shash_desc *shash = (struct shash_desc *)sdesc;
+   u32 *ctx = (u32 *)shash_desc_ctx(shash);
 
-   sdesc.shash.tfm = tfm;
-   sdesc.shash.flags = 0;
+   shash->tfm = tfm;
+   shash->flags = 0;
 
-   *(u32 *)sdesc.ctx = le32_to_cpu(420553207);
-   err = crypto_shash_final(, (u8 *));
+   *ctx = le32_to_cpu(420553207);
+   err = crypto_shash_final(shash, (u8 *));
if (err) {
printk(KERN_ERR "alg: crc32c: Operation failed for "
   "%s: %d\n", driver, err);
-- 
1.7.9.5

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


[PATCH V2 1/2] Remove VLAIS usage from crypto/hmac.c

2012-10-31 Thread Behan Webster
From: Jan-Simon Möller 

The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This patch instead allocates the appropriate amount of memory
using an char array.

Patch from series at
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120507/142707.html
by PaX Team.

Signed-off-by: Jan-Simon Möller 
Cc: pagee...@freemail.hu
Signed-off-by: Behan Webster 
---
 crypto/hmac.c |   27 +--
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/crypto/hmac.c b/crypto/hmac.c
index 8d9544c..1061255 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -52,20 +52,19 @@ static int hmac_setkey(struct crypto_shash *parent,
struct hmac_ctx *ctx = align_ptr(opad + ss,
 crypto_tfm_ctx_alignment());
struct crypto_shash *hash = ctx->hash;
-   struct {
-   struct shash_desc shash;
-   char ctx[crypto_shash_descsize(hash)];
-   } desc;
+   char desc[sizeof(struct shash_desc) + crypto_shash_descsize(hash)
+   + CRYPTO_MINALIGN] CRYPTO_MINALIGN_ATTR;
+   struct shash_desc *shash = (struct shash_desc *)desc;
unsigned int i;
 
-   desc.shash.tfm = hash;
-   desc.shash.flags = crypto_shash_get_flags(parent) &
-   CRYPTO_TFM_REQ_MAY_SLEEP;
+   shash->tfm = hash;
+   shash->flags = crypto_shash_get_flags(parent)
+   & CRYPTO_TFM_REQ_MAY_SLEEP;
 
if (keylen > bs) {
int err;
 
-   err = crypto_shash_digest(, inkey, keylen, ipad);
+   err = crypto_shash_digest(shash, inkey, keylen, ipad);
if (err)
return err;
 
@@ -81,12 +80,12 @@ static int hmac_setkey(struct crypto_shash *parent,
opad[i] ^= 0x5c;
}
 
-   return crypto_shash_init() ?:
-  crypto_shash_update(, ipad, bs) ?:
-  crypto_shash_export(, ipad) ?:
-  crypto_shash_init() ?:
-  crypto_shash_update(, opad, bs) ?:
-  crypto_shash_export(, opad);
+   return crypto_shash_init(shash) ?:
+  crypto_shash_update(shash, ipad, bs) ?:
+  crypto_shash_export(shash, ipad) ?:
+  crypto_shash_init(shash) ?:
+  crypto_shash_update(shash, opad, bs) ?:
+  crypto_shash_export(shash, opad);
 }
 
 static int hmac_export(struct shash_desc *pdesc, void *out)
-- 
1.7.9.5

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


[PATCH V2 1/2] Remove VLAIS usage from crypto/hmac.c

2012-10-31 Thread Behan Webster
From: Jan-Simon Möller dl...@gmx.de

The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This patch instead allocates the appropriate amount of memory
using an char array.

Patch from series at
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120507/142707.html
by PaX Team.

Signed-off-by: Jan-Simon Möller dl...@gmx.de
Cc: pagee...@freemail.hu
Signed-off-by: Behan Webster beh...@converseincode.com
---
 crypto/hmac.c |   27 +--
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/crypto/hmac.c b/crypto/hmac.c
index 8d9544c..1061255 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -52,20 +52,19 @@ static int hmac_setkey(struct crypto_shash *parent,
struct hmac_ctx *ctx = align_ptr(opad + ss,
 crypto_tfm_ctx_alignment());
struct crypto_shash *hash = ctx-hash;
-   struct {
-   struct shash_desc shash;
-   char ctx[crypto_shash_descsize(hash)];
-   } desc;
+   char desc[sizeof(struct shash_desc) + crypto_shash_descsize(hash)
+   + CRYPTO_MINALIGN] CRYPTO_MINALIGN_ATTR;
+   struct shash_desc *shash = (struct shash_desc *)desc;
unsigned int i;
 
-   desc.shash.tfm = hash;
-   desc.shash.flags = crypto_shash_get_flags(parent) 
-   CRYPTO_TFM_REQ_MAY_SLEEP;
+   shash-tfm = hash;
+   shash-flags = crypto_shash_get_flags(parent)
+CRYPTO_TFM_REQ_MAY_SLEEP;
 
if (keylen  bs) {
int err;
 
-   err = crypto_shash_digest(desc.shash, inkey, keylen, ipad);
+   err = crypto_shash_digest(shash, inkey, keylen, ipad);
if (err)
return err;
 
@@ -81,12 +80,12 @@ static int hmac_setkey(struct crypto_shash *parent,
opad[i] ^= 0x5c;
}
 
-   return crypto_shash_init(desc.shash) ?:
-  crypto_shash_update(desc.shash, ipad, bs) ?:
-  crypto_shash_export(desc.shash, ipad) ?:
-  crypto_shash_init(desc.shash) ?:
-  crypto_shash_update(desc.shash, opad, bs) ?:
-  crypto_shash_export(desc.shash, opad);
+   return crypto_shash_init(shash) ?:
+  crypto_shash_update(shash, ipad, bs) ?:
+  crypto_shash_export(shash, ipad) ?:
+  crypto_shash_init(shash) ?:
+  crypto_shash_update(shash, opad, bs) ?:
+  crypto_shash_export(shash, opad);
 }
 
 static int hmac_export(struct shash_desc *pdesc, void *out)
-- 
1.7.9.5

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


[PATCH V2 2/2] Remove VLAIS usage from crypto/testmgr.c

2012-10-31 Thread Behan Webster
From: Jan-Simon Möller dl...@gmx.de

The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This patch instead allocates the appropriate amount of memory
using an char array.

Patch from series at
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120507/142707.html
by PaX Team.

Signed-off-by: Jan-Simon Möller dl...@gmx.de
Cc: pagee...@freemail.hu
[Use shash_desc_ctx() to calculate address of ctx]
Signed-off-by: Behan Webster beh...@converseincode.com
---
 crypto/testmgr.c |   17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 941d75c..8738ff4 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -1578,16 +1578,17 @@ static int alg_test_crc32c(const struct alg_test_desc 
*desc,
}
 
do {
-   struct {
-   struct shash_desc shash;
-   char ctx[crypto_shash_descsize(tfm)];
-   } sdesc;
+   char sdesc[sizeof(struct shash_desc)
+   + crypto_shash_descsize(tfm)
+   + CRYPTO_MINALIGN] CRYPTO_MINALIGN_ATTR;
+   struct shash_desc *shash = (struct shash_desc *)sdesc;
+   u32 *ctx = (u32 *)shash_desc_ctx(shash);
 
-   sdesc.shash.tfm = tfm;
-   sdesc.shash.flags = 0;
+   shash-tfm = tfm;
+   shash-flags = 0;
 
-   *(u32 *)sdesc.ctx = le32_to_cpu(420553207);
-   err = crypto_shash_final(sdesc.shash, (u8 *)val);
+   *ctx = le32_to_cpu(420553207);
+   err = crypto_shash_final(shash, (u8 *)val);
if (err) {
printk(KERN_ERR alg: crc32c: Operation failed for 
   %s: %d\n, driver, err);
-- 
1.7.9.5

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


[PATCH V2] Remove VLAIS usage from libcrc32c.c

2012-10-31 Thread Behan Webster
From: Jan-Simon Möller dl...@gmx.de

The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This patch instead allocates the appropriate amount of memory
using an char array.

Patch from series at
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120507/142707.html
by PaX Team.

Signed-off-by: Jan-Simon Möller dl...@gmx.de
Cc: pagee...@freemail.hu
[Use shash_desc_ctx() to calculate address of ctx]
Signed-off-by: Behan Webster beh...@converseincode.com
---
 lib/libcrc32c.c |   18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/lib/libcrc32c.c b/lib/libcrc32c.c
index 244f548..c155b3f 100644
--- a/lib/libcrc32c.c
+++ b/lib/libcrc32c.c
@@ -41,20 +41,20 @@ static struct crypto_shash *tfm;
 
 u32 crc32c(u32 crc, const void *address, unsigned int length)
 {
-   struct {
-   struct shash_desc shash;
-   char ctx[crypto_shash_descsize(tfm)];
-   } desc;
+   char desc[sizeof(struct shash_desc) + crypto_shash_descsize(tfm)
+   + CRYPTO_MINALIGN] CRYPTO_MINALIGN_ATTR;
+   struct shash_desc *shash = (struct shash_desc *)desc;
+   u32 *ctx = (u32 *)shash_desc_ctx(shash);
int err;
 
-   desc.shash.tfm = tfm;
-   desc.shash.flags = 0;
-   *(u32 *)desc.ctx = crc;
+   shash-tfm = tfm;
+   shash-flags = 0;
+   *ctx = crc;
 
-   err = crypto_shash_update(desc.shash, address, length);
+   err = crypto_shash_update(shash, address, length);
BUG_ON(err);
 
-   return *(u32 *)desc.ctx;
+   return *ctx;
 }
 
 EXPORT_SYMBOL(crc32c);
-- 
1.7.9.5

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


Re: [PATCH V2 2/3] Remove VLAIS usage from gadget code

2012-10-31 Thread Behan Webster

On 12-10-31 09:28 AM, Felipe Balbi wrote:

hi,

On Tue, Oct 30, 2012 at 05:18:56PM -0400, Behan Webster wrote:

The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This patch instead calculates offsets into the kmalloc-ed
memory buffer using macros from valign.h.

Signed-off-by: Behan Webster beh...@converseincode.com

this won't apply after the current cleanups I applied to gadget code
from Sebastian.

Makes sense. I'll try it with your repo, and regenerate.


If someone takes this patch, it will generate a series of annoying,
hard-to-figure-out conflicts (at least judging by the looks of
$SUBJECT).
I just tried the patch on your git.kernel.org repo and thankfully there 
is only one hunk which is rejected, and fortunately the reason is 
trivial (descriptors - fs_descriptors).


Was:
-func-function.descriptors = data-fs_descs;
+func-function.descriptors = fs_descs;

Now is:
-func-function.fs_descriptors = data-fs_descs;
+func-function.fs_descriptors = fs_descs;

I will regenerate the patch set, but obviously the new gadget patch in 
the V3 patchset will only apply to the USB repo, and not to the 
netfilter repo.


Thanks,

Behan

--
Behan Webster
beh...@converseincode.com

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


[PATCH V2 1/3] Helper macros used for replacing the use of VLAIS

2012-10-30 Thread Behan Webster
The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This new header file contains macros which can be used to
calculate the size and offset of variables in an allocated buffer of memory
taking into account alignment issues.

Signed-off-by: Behan Webster 
---
 include/linux/valign.h |   87 
 1 file changed, 87 insertions(+)
 create mode 100644 include/linux/valign.h

diff --git a/include/linux/valign.h b/include/linux/valign.h
new file mode 100644
index 000..b39381b
--- /dev/null
+++ b/include/linux/valign.h
@@ -0,0 +1,87 @@
+/*
+ * Variable alignment macros used to break up a larger chunk of memory into
+ * smaller variables. Meant to be used to replace the use of Variable Length
+ * Arrays In Structures (VLAIS)
+ *
+ *  Copyright (C) 2012 Behan Webster 
+ */
+
+#ifndef _VALIGN_H_
+#define _VALIGN_H_
+
+/**
+ * truncalign() - Align a memory address by truncation
+ * @num:   Address or size to align
+ * @padwidth:  Number of byte upon which to align
+ *
+ * Truncate an address or size to a particular memory alignment.
+ * Used by truncalign().
+ */
+#define truncalign(num, padwidth) ((long)(num) & ~((padwidth)-1))
+
+/**
+ * padalign() - Align a memory address by padding
+ * @num:   Address or size to align
+ * @padwidth:  Number of byte upon which to align
+ *
+ * Pad out an address or size to a particular memory alignment
+ * Used by paddedsize() and paddedstart().
+ */
+#define padalign(num, padwidth) \
+   truncalign((long)(num) + ((padwidth)-1), padwidth)
+
+/**
+ * paddedsize() - Calculate the size of an chunk of aligned memory
+ * @offset:Unaligned offset to the start of the chunk size being calculated
+ * @num:   The number of variables in the array of "type" (can be 1)
+ * @type:  The type of variables in the array
+ * @nexttype:  The type of the next variable in the large piece of memory
+ *
+ * Calculate the size that a variable (or array) will take as a part of a
+ * larger piece of memory.  Takes into account a potentially unaligned offset
+ * into the larger piece of allocated memory, the alignment of the variable
+ * type, and the alignement of the type of the variable to be used after that.
+ *
+ * Example: size_t l = paddedsize(1, 2, short, int);
+ *
+ * The example above would give you a padded size of 6 bytes: 2x 16-bit shorts,
+ * starting at 2 bytes into the buffer (the offset of 1 byte being padded out
+ * to 2 bytes) followed by 2 bytes of padding so that the next type (a 32-bit
+ * int) would be 32-bit aligned. looking like this:
+ *
+ *   0: O.SS SS.. 
+ *\-/ <-- 2 shorts + 2 bytes of padding = size of 6 bytes
+ *
+ * O = The offset
+ * . = Padding bytes
+ * S = 2 shorts
+ * i = int which will theoretically be next
+ */
+#define paddedsize(offset, num, type, nexttype) (padalign((offset) \
+   + (num) * sizeof(type), __alignof__(nexttype)) - (offset))
+
+/**
+ * paddedstart() - Calculate the start of a chunk of aligned memory
+ * @ptr:   Pointer from which to calculate the start of the chunk
+ * @offset:Offset from the ptr to the start of the chunk being calculated
+ * @type:  The type of variable in the chunk of memory
+ *
+ * Calculate the start address of a variable based on the offset from an
+ * address, aligned based on the type of the variable specified.
+ *
+ * Example: char *data = kmalloc(size, GFP_KERNEL);
+ *  long *var = paddedstart(data, 12, long);
+ *
+ * The example above on a 64-bit machine would return the equivalent of
+ * [16] since a long needs to be 8 byte aligned.
+ *
+ *   0:      
+ *  ^ <-- The start address of the long
+ * O = The offset
+ * . = Padding bytes
+ * L = The long
+ */
+#define paddedstart(ptr, offset, type) \
+   (type *)padalign((long)(ptr)+(offset), __alignof__(type))
+
+#endif
-- 
1.7.9.5

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


[PATCH V2 2/3] Remove VLAIS usage from gadget code

2012-10-30 Thread Behan Webster
The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This patch instead calculates offsets into the kmalloc-ed
memory buffer using macros from valign.h.

Signed-off-by: Behan Webster 
---
 drivers/usb/gadget/f_fs.c |  106 ++---
 1 file changed, 61 insertions(+), 45 deletions(-)

diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index 64c4ec1..ca6cacc 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -1875,6 +1876,15 @@ error:
return ret;
 }
 
+static void __ffs_init_stringtabs(struct usb_gadget_strings **stringtabs,
+   struct usb_gadget_strings *t, unsigned len)
+{
+   do {
+   *stringtabs++ = t++;
+   } while (--len);
+   *stringtabs = NULL;
+}
+
 static int __ffs_data_got_strings(struct ffs_data *ffs,
  char *const _data, size_t len)
 {
@@ -1911,31 +1921,26 @@ static int __ffs_data_got_strings(struct ffs_data *ffs,
 
/* Allocate everything in one chunk so there's less maintenance. */
{
-   struct {
-   struct usb_gadget_strings *stringtabs[lang_count + 1];
-   struct usb_gadget_strings stringtab[lang_count];
-   struct usb_string strings[lang_count*(needed_count+1)];
-   } *d;
-   unsigned i = 0;
-
-   d = kmalloc(sizeof *d, GFP_KERNEL);
+   int strtabslen = paddedsize(0, lang_count+1,
+   struct usb_gadget_strings *, struct usb_gadget_strings);
+   int strtablen = paddedsize(strtabslen, lang_count,
+   struct usb_gadget_strings, struct usb_string);
+   int strlen = paddedsize(strtabslen + strtablen,
+   lang_count*(needed_count+1), struct usb_string, int);
+
+   stringtabs = kmalloc(strtabslen + strtablen + strlen,
+   GFP_KERNEL);
if (unlikely(!d)) {
kfree(_data);
return -ENOMEM;
}
 
-   stringtabs = d->stringtabs;
-   t = d->stringtab;
-   i = lang_count;
-   do {
-   *stringtabs++ = t++;
-   } while (--i);
-   *stringtabs = NULL;
-
-   stringtabs = d->stringtabs;
-   t = d->stringtab;
-   s = d->strings;
+   t = paddedstart(stringtabs, strtabslen,
+   struct usb_gadget_strings);
+   s = paddedstart(t, strtablen, struct usb_string);
strings = s;
+
+   __ffs_init_stringtabs(stringtabs, t, lang_count);
}
 
/* For each language */
@@ -2209,17 +2214,23 @@ static int ffs_func_bind(struct usb_configuration *c,
 
int ret;
 
-   /* Make it a single chunk, less management later on */
-   struct {
-   struct ffs_ep eps[ffs->eps_count];
-   struct usb_descriptor_header
-   *fs_descs[full ? ffs->fs_descs_count + 1 : 0];
-   struct usb_descriptor_header
-   *hs_descs[high ? ffs->hs_descs_count + 1 : 0];
-   short inums[ffs->interfaces_count];
-   char raw_descs[high ? ffs->raw_descs_length
-   : ffs->raw_fs_descs_length];
-   } *data;
+   struct ffs_ep *eps;
+   struct usb_descriptor_header **fs_descs;
+   struct usb_descriptor_header **hs_descs;
+   short *inums;
+   char *raw_descs;
+
+   int epslen = paddedsize(0, ffs->eps_count,
+   struct ffs_ep, struct usb_descriptor_header);
+   int fsdlen = paddedsize(epslen, full ? ffs->fs_descs_count + 1 : 0,
+   struct usb_descriptor_header,
+   struct usb_descriptor_header);
+   int hsdlen = paddedsize(fsdlen, high ? ffs->hs_descs_count + 1 : 0,
+   struct usb_descriptor_header, short);
+   int inumlen = paddedsize(hsdlen, ffs->interfaces_count, short, char);
+   int rawlen = paddedsize(inumlen,
+   high ? ffs->raw_descs_length : ffs->raw_fs_descs_length,
+   char, int);
 
ENTER();
 
@@ -2227,21 +2238,28 @@ static int ffs_func_bind(struct usb_configuration *c,
if (unlikely(!(full | high)))
return -ENOTSUPP;
 
-   /* Allocate */
-   data = kmalloc(sizeof *data, GFP_KERNEL);
+   /* Allocate a single chunk, less management later on */
+   eps = kmalloc(epslen+fsdlen+hsdlen+inumlen+rawlen, GFP_KERNEL);
if (unlikely(!data))
return -EN

[PATCH V2 3/3] Remove VLAIS usage from netfilter

2012-10-30 Thread Behan Webster
From: Jan-Simon Möller 

The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This patch instead calculates offsets into the kmalloc-ed
memory buffer using macros from valign.h.

Patch from series at
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120507/142707.html
by PaX Team.

Signed-off-by: Jan-Simon Möller 
Cc: pagee...@freemail.hu
[Modified to use macros from valign.h]
Signed-off-by: Behan Webster 
---
 net/netfilter/xt_repldata.h |   40 
 1 file changed, 24 insertions(+), 16 deletions(-)

diff --git a/net/netfilter/xt_repldata.h b/net/netfilter/xt_repldata.h
index 6efe4e5..d2b4232 100644
--- a/net/netfilter/xt_repldata.h
+++ b/net/netfilter/xt_repldata.h
@@ -5,31 +5,39 @@
  * they serve as the hanging-off data accessed through repl.data[].
  */
 
+#include 
+
 #define xt_alloc_initial_table(type, typ2) ({ \
unsigned int hook_mask = info->valid_hooks; \
unsigned int nhooks = hweight32(hook_mask); \
unsigned int bytes = 0, hooknum = 0, i = 0; \
-   struct { \
-   struct type##_replace repl; \
-   struct type##_standard entries[nhooks]; \
-   struct type##_error term; \
-   } *tbl = kzalloc(sizeof(*tbl), GFP_KERNEL); \
-   if (tbl == NULL) \
+   int replsize = paddedsize(0, 1, \
+   struct type##_replace, struct type##_standard); \
+   int entsize = paddedsize(replsize, nhooks, \
+   struct type##_standard, struct type##_error); \
+   int termsize = paddedsize(replsize+entsize, 1, \
+   struct type##_error, int); \
+   struct type##_replace *repl = kzalloc(replsize+entsize+termsize, \
+   GFP_KERNEL); \
+   if (repl == NULL) \
return NULL; \
-   strncpy(tbl->repl.name, info->name, sizeof(tbl->repl.name)); \
-   tbl->term = (struct type##_error)typ2##_ERROR_INIT;  \
-   tbl->repl.valid_hooks = hook_mask; \
-   tbl->repl.num_entries = nhooks + 1; \
-   tbl->repl.size = nhooks * sizeof(struct type##_standard) + \
-sizeof(struct type##_error); \
+   struct type##_standard *entries = paddedstart(repl, replsize, \
+   struct type##_standard); \
+   struct type##_error *term = paddedstart(entries, entsize, \
+   struct type##_error); \
+   strncpy(repl->name, info->name, sizeof(repl->name)); \
+   *term = (struct type##_error)typ2##_ERROR_INIT;  \
+   repl->valid_hooks = hook_mask; \
+   repl->num_entries = nhooks + 1; \
+   repl->size = entsize+termsize; \
for (; hook_mask != 0; hook_mask >>= 1, ++hooknum) { \
if (!(hook_mask & 1)) \
continue; \
-   tbl->repl.hook_entry[hooknum] = bytes; \
-   tbl->repl.underflow[hooknum]  = bytes; \
-   tbl->entries[i++] = (struct type##_standard) \
+   repl->hook_entry[hooknum] = bytes; \
+   repl->underflow[hooknum]  = bytes; \
+   entries[i++] = (struct type##_standard) \
typ2##_STANDARD_INIT(NF_ACCEPT); \
bytes += sizeof(struct type##_standard); \
} \
-   tbl; \
+   repl; \
 })
-- 
1.7.9.5

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


[PATCH V2 0/3] Removing the use of VLAIS from USB Gadget and netfilter

2012-10-30 Thread Behan Webster
This is a V2 version of the patch set I previously sent out. Since the use of a
new valign.h file spans both the USB and netfilter subsystems, I should have
sent out all 3 patches to both trees at once. Assuming all is well, hopefully
both subsystems can cooperate to get these patches in without causing
conflicts.

The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). The LLVMLinux Project is working towards the ability of
providing the Linux kernel developer the choice of using the Clang compiler
toolchain. This is a part of a series of patches which remove the use of VLAIS
from crypto code, dm-crypt, jbd2, libcrc32c, netfilter, and usb gadget. Other
patches to allow Clang to be used to compile the Linux kernel will follow.

Behan Webster (2):
  Helper macros used for replacing the use of VLAIS
  Remove VLAIS usage from gadget code

Jan-Simon Möller (1):
  Remove VLAIS usage from netfilter

 drivers/usb/gadget/f_fs.c   |  106 +--
 include/linux/valign.h  |   87 +++
 net/netfilter/xt_repldata.h |   40 +---
 3 files changed, 172 insertions(+), 61 deletions(-)
 create mode 100644 include/linux/valign.h

-- 
1.7.9.5

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


Re: [PATCH 1/2] Helper macros used for replacing the use of VLAIS

2012-10-30 Thread Behan Webster

On 12-10-30 03:20 PM, Greg KH wrote:

On Tue, Oct 30, 2012 at 02:25:19PM -0400, Behan Webster wrote:

The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This new header file contains macros which can be used to
calculate the size and offset of variables in an allocated buffer of memory
taking into account alignment issues.

Signed-off-by: Behan Webster 
---
  include/linux/valign.h |   87 
  1 file changed, 87 insertions(+)
  create mode 100644 include/linux/valign.h

You sent the same patch here, to two different trees (usb and
networking).  That's not good, what happens if they both apply them?

Good point. My mistake.

People in both subsystems needed to see the patch which is why I sent them.

What would have been a better approach? And how can I fix this?

Behan

--
Behan Webster
beh...@converseincode.com

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


[PATCH] Remove VLAIS usage from libcrc32c.c

2012-10-30 Thread Behan Webster
From: Jan-Simon Möller 

The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This patch instead allocates the appropriate amount of memory
using an char array.

Patch from series at
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120507/142707.html
by PaX Team.

Signed-off-by: Jan-Simon Möller 
Cc: pagee...@freemail.hu
Signed-off-by: Behan Webster 
---
 lib/libcrc32c.c |   19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/lib/libcrc32c.c b/lib/libcrc32c.c
index 244f548..5d0bac8 100644
--- a/lib/libcrc32c.c
+++ b/lib/libcrc32c.c
@@ -41,20 +41,21 @@ static struct crypto_shash *tfm;
 
 u32 crc32c(u32 crc, const void *address, unsigned int length)
 {
-   struct {
-   struct shash_desc shash;
-   char ctx[crypto_shash_descsize(tfm)];
-   } desc;
+   char desc[sizeof(struct shash_desc) + crypto_shash_descsize(tfm)
+   + CRYPTO_MINALIGN] CRYPTO_MINALIGN_ATTR;
+   struct shash_desc *shash = (struct shash_desc *)desc;
+   u32 *ctx = (u32 *)((unsigned long)(desc + sizeof(struct shash_desc)
+   + CRYPTO_MINALIGN - 1) & ~(CRYPTO_MINALIGN - 1));
int err;
 
-   desc.shash.tfm = tfm;
-   desc.shash.flags = 0;
-   *(u32 *)desc.ctx = crc;
+   shash->tfm = tfm;
+   shash->flags = 0;
+   *ctx = crc;
 
-   err = crypto_shash_update(, address, length);
+   err = crypto_shash_update(shash, address, length);
BUG_ON(err);
 
-   return *(u32 *)desc.ctx;
+   return *ctx;
 }
 
 EXPORT_SYMBOL(crc32c);
-- 
1.7.9.5

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


[PATCH 2/2] Remove VLAIS usage from netfilter

2012-10-30 Thread Behan Webster
From: Jan-Simon Möller 

The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This patch instead calculates offsets into the kmalloc-ed
memory buffer using macros from valign.h.

Patch from series at
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120507/142707.html
by PaX Team.

Signed-off-by: Jan-Simon Möller 
Cc: pagee...@freemail.hu
[Modified to use macros from valign.h]
Signed-off-by: Behan Webster 
---
 net/netfilter/xt_repldata.h |   40 
 1 file changed, 24 insertions(+), 16 deletions(-)

diff --git a/net/netfilter/xt_repldata.h b/net/netfilter/xt_repldata.h
index 6efe4e5..d2b4232 100644
--- a/net/netfilter/xt_repldata.h
+++ b/net/netfilter/xt_repldata.h
@@ -5,31 +5,39 @@
  * they serve as the hanging-off data accessed through repl.data[].
  */
 
+#include 
+
 #define xt_alloc_initial_table(type, typ2) ({ \
unsigned int hook_mask = info->valid_hooks; \
unsigned int nhooks = hweight32(hook_mask); \
unsigned int bytes = 0, hooknum = 0, i = 0; \
-   struct { \
-   struct type##_replace repl; \
-   struct type##_standard entries[nhooks]; \
-   struct type##_error term; \
-   } *tbl = kzalloc(sizeof(*tbl), GFP_KERNEL); \
-   if (tbl == NULL) \
+   int replsize = paddedsize(0, 1, \
+   struct type##_replace, struct type##_standard); \
+   int entsize = paddedsize(replsize, nhooks, \
+   struct type##_standard, struct type##_error); \
+   int termsize = paddedsize(replsize+entsize, 1, \
+   struct type##_error, int); \
+   struct type##_replace *repl = kzalloc(replsize+entsize+termsize, \
+   GFP_KERNEL); \
+   if (repl == NULL) \
return NULL; \
-   strncpy(tbl->repl.name, info->name, sizeof(tbl->repl.name)); \
-   tbl->term = (struct type##_error)typ2##_ERROR_INIT;  \
-   tbl->repl.valid_hooks = hook_mask; \
-   tbl->repl.num_entries = nhooks + 1; \
-   tbl->repl.size = nhooks * sizeof(struct type##_standard) + \
-sizeof(struct type##_error); \
+   struct type##_standard *entries = paddedstart(repl, replsize, \
+   struct type##_standard); \
+   struct type##_error *term = paddedstart(entries, entsize, \
+   struct type##_error); \
+   strncpy(repl->name, info->name, sizeof(repl->name)); \
+   *term = (struct type##_error)typ2##_ERROR_INIT;  \
+   repl->valid_hooks = hook_mask; \
+   repl->num_entries = nhooks + 1; \
+   repl->size = entsize+termsize; \
for (; hook_mask != 0; hook_mask >>= 1, ++hooknum) { \
if (!(hook_mask & 1)) \
continue; \
-   tbl->repl.hook_entry[hooknum] = bytes; \
-   tbl->repl.underflow[hooknum]  = bytes; \
-   tbl->entries[i++] = (struct type##_standard) \
+   repl->hook_entry[hooknum] = bytes; \
+   repl->underflow[hooknum]  = bytes; \
+   entries[i++] = (struct type##_standard) \
typ2##_STANDARD_INIT(NF_ACCEPT); \
bytes += sizeof(struct type##_standard); \
} \
-   tbl; \
+   repl; \
 })
-- 
1.7.9.5

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


[PATCH 1/2] Helper macros used for replacing the use of VLAIS

2012-10-30 Thread Behan Webster
The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This new header file contains macros which can be used to
calculate the size and offset of variables in an allocated buffer of memory
taking into account alignment issues.

Signed-off-by: Behan Webster 
---
 include/linux/valign.h |   87 
 1 file changed, 87 insertions(+)
 create mode 100644 include/linux/valign.h

diff --git a/include/linux/valign.h b/include/linux/valign.h
new file mode 100644
index 000..b39381b
--- /dev/null
+++ b/include/linux/valign.h
@@ -0,0 +1,87 @@
+/*
+ * Variable alignment macros used to break up a larger chunk of memory into
+ * smaller variables. Meant to be used to replace the use of Variable Length
+ * Arrays In Structures (VLAIS)
+ *
+ *  Copyright (C) 2012 Behan Webster 
+ */
+
+#ifndef _VALIGN_H_
+#define _VALIGN_H_
+
+/**
+ * truncalign() - Align a memory address by truncation
+ * @num:   Address or size to align
+ * @padwidth:  Number of byte upon which to align
+ *
+ * Truncate an address or size to a particular memory alignment.
+ * Used by truncalign().
+ */
+#define truncalign(num, padwidth) ((long)(num) & ~((padwidth)-1))
+
+/**
+ * padalign() - Align a memory address by padding
+ * @num:   Address or size to align
+ * @padwidth:  Number of byte upon which to align
+ *
+ * Pad out an address or size to a particular memory alignment
+ * Used by paddedsize() and paddedstart().
+ */
+#define padalign(num, padwidth) \
+   truncalign((long)(num) + ((padwidth)-1), padwidth)
+
+/**
+ * paddedsize() - Calculate the size of an chunk of aligned memory
+ * @offset:Unaligned offset to the start of the chunk size being calculated
+ * @num:   The number of variables in the array of "type" (can be 1)
+ * @type:  The type of variables in the array
+ * @nexttype:  The type of the next variable in the large piece of memory
+ *
+ * Calculate the size that a variable (or array) will take as a part of a
+ * larger piece of memory.  Takes into account a potentially unaligned offset
+ * into the larger piece of allocated memory, the alignment of the variable
+ * type, and the alignement of the type of the variable to be used after that.
+ *
+ * Example: size_t l = paddedsize(1, 2, short, int);
+ *
+ * The example above would give you a padded size of 6 bytes: 2x 16-bit shorts,
+ * starting at 2 bytes into the buffer (the offset of 1 byte being padded out
+ * to 2 bytes) followed by 2 bytes of padding so that the next type (a 32-bit
+ * int) would be 32-bit aligned. looking like this:
+ *
+ *   0: O.SS SS.. 
+ *\-/ <-- 2 shorts + 2 bytes of padding = size of 6 bytes
+ *
+ * O = The offset
+ * . = Padding bytes
+ * S = 2 shorts
+ * i = int which will theoretically be next
+ */
+#define paddedsize(offset, num, type, nexttype) (padalign((offset) \
+   + (num) * sizeof(type), __alignof__(nexttype)) - (offset))
+
+/**
+ * paddedstart() - Calculate the start of a chunk of aligned memory
+ * @ptr:   Pointer from which to calculate the start of the chunk
+ * @offset:Offset from the ptr to the start of the chunk being calculated
+ * @type:  The type of variable in the chunk of memory
+ *
+ * Calculate the start address of a variable based on the offset from an
+ * address, aligned based on the type of the variable specified.
+ *
+ * Example: char *data = kmalloc(size, GFP_KERNEL);
+ *  long *var = paddedstart(data, 12, long);
+ *
+ * The example above on a 64-bit machine would return the equivalent of
+ * [16] since a long needs to be 8 byte aligned.
+ *
+ *   0:      
+ *  ^ <-- The start address of the long
+ * O = The offset
+ * . = Padding bytes
+ * L = The long
+ */
+#define paddedstart(ptr, offset, type) \
+   (type *)padalign((long)(ptr)+(offset), __alignof__(type))
+
+#endif
-- 
1.7.9.5

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


[PATCH 0/2] Removing the use of VLAIS from netfilter

2012-10-30 Thread Behan Webster
The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). The LLVMLinux Project is working towards the ability of
providing the Linux kernel developer the choice of using the Clang compiler
toolchain. This is a part of a series of patches which remove the use of VLAIS
from crypto code, dm-crypt, jbd2, libcrc32c, netfilter, and usb gadget. Other
patches to allow Clang to be used will follow.

Behan Webster (1):
  Helper macros used for replacing the use of VLAIS

Jan-Simon Möller (1):
  Remove VLAIS usage from netfilter

 include/linux/valign.h  |   87 +++
 net/netfilter/xt_repldata.h |   40 
 2 files changed, 111 insertions(+), 16 deletions(-)
 create mode 100644 include/linux/valign.h

-- 
1.7.9.5

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


[PATCH 1/2] Remove VLAIS usage from crypto/hmac.c

2012-10-30 Thread Behan Webster
From: Jan-Simon Möller 

The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This patch instead allocates the appropriate amount of memory
using an char array.

Patch from series at
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120507/142707.html
by PaX Team.

Signed-off-by: Jan-Simon Möller 
Cc: pagee...@freemail.hu
Signed-off-by: Behan Webster 
---
 crypto/hmac.c |   27 +--
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/crypto/hmac.c b/crypto/hmac.c
index 8d9544c..1061255 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -52,20 +52,19 @@ static int hmac_setkey(struct crypto_shash *parent,
struct hmac_ctx *ctx = align_ptr(opad + ss,
 crypto_tfm_ctx_alignment());
struct crypto_shash *hash = ctx->hash;
-   struct {
-   struct shash_desc shash;
-   char ctx[crypto_shash_descsize(hash)];
-   } desc;
+   char desc[sizeof(struct shash_desc) + crypto_shash_descsize(hash)
+   + CRYPTO_MINALIGN] CRYPTO_MINALIGN_ATTR;
+   struct shash_desc *shash = (struct shash_desc *)desc;
unsigned int i;
 
-   desc.shash.tfm = hash;
-   desc.shash.flags = crypto_shash_get_flags(parent) &
-   CRYPTO_TFM_REQ_MAY_SLEEP;
+   shash->tfm = hash;
+   shash->flags = crypto_shash_get_flags(parent)
+   & CRYPTO_TFM_REQ_MAY_SLEEP;
 
if (keylen > bs) {
int err;
 
-   err = crypto_shash_digest(, inkey, keylen, ipad);
+   err = crypto_shash_digest(shash, inkey, keylen, ipad);
if (err)
return err;
 
@@ -81,12 +80,12 @@ static int hmac_setkey(struct crypto_shash *parent,
opad[i] ^= 0x5c;
}
 
-   return crypto_shash_init() ?:
-  crypto_shash_update(, ipad, bs) ?:
-  crypto_shash_export(, ipad) ?:
-  crypto_shash_init() ?:
-  crypto_shash_update(, opad, bs) ?:
-  crypto_shash_export(, opad);
+   return crypto_shash_init(shash) ?:
+  crypto_shash_update(shash, ipad, bs) ?:
+  crypto_shash_export(shash, ipad) ?:
+  crypto_shash_init(shash) ?:
+  crypto_shash_update(shash, opad, bs) ?:
+  crypto_shash_export(shash, opad);
 }
 
 static int hmac_export(struct shash_desc *pdesc, void *out)
-- 
1.7.9.5

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


[PATCH 0/2] Removing the use of VLAIS from the Linux Kernel

2012-10-30 Thread Behan Webster
The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). The LLVMLinux Project is working towards the ability of
providing the Linux kernel developer the choice of using the Clang compiler
toolchain. This is a part of a series of patches which remove the use of VLAIS
from crypto code, dm-crypt, jbd2, libcrc32c, netfilter, and usb gadget. Other
patches to allow Clang to be used will follow.

Jan-Simon Möller (2):
  Remove VLAIS usage from crypto/hmac.c
  Remove VLAIS usage from crypto/testmgr.c

 crypto/hmac.c|   27 +--
 crypto/testmgr.c |   23 +--
 2 files changed, 26 insertions(+), 24 deletions(-)

-- 
1.7.9.5

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


[PATCH 2/2] Remove VLAIS usage from crypto/testmgr.c

2012-10-30 Thread Behan Webster
From: Jan-Simon Möller 

The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This patch instead allocates the appropriate amount of memory
using an char array.

Patch from series at
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120507/142707.html
by PaX Team.

Signed-off-by: Jan-Simon Möller 
Cc: pagee...@freemail.hu
Signed-off-by: Behan Webster 
---
 crypto/testmgr.c |   23 +--
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 941d75c..5b7b3a6 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -1578,16 +1578,19 @@ static int alg_test_crc32c(const struct alg_test_desc 
*desc,
}
 
do {
-   struct {
-   struct shash_desc shash;
-   char ctx[crypto_shash_descsize(tfm)];
-   } sdesc;
-
-   sdesc.shash.tfm = tfm;
-   sdesc.shash.flags = 0;
-
-   *(u32 *)sdesc.ctx = le32_to_cpu(420553207);
-   err = crypto_shash_final(, (u8 *));
+   char sdesc[sizeof(struct shash_desc)
+   + crypto_shash_descsize(tfm)
+   + CRYPTO_MINALIGN] CRYPTO_MINALIGN_ATTR;
+   struct shash_desc *shash = (struct shash_desc *)sdesc;
+   u32 *ctx = (u32 *)((unsigned long)(sdesc
+   + sizeof(struct shash_desc) + CRYPTO_MINALIGN - 1)
+   & ~(CRYPTO_MINALIGN - 1));
+
+   shash->tfm = tfm;
+   shash->flags = 0;
+
+   *ctx = le32_to_cpu(420553207);
+   err = crypto_shash_final(shash, (u8 *));
if (err) {
printk(KERN_ERR "alg: crc32c: Operation failed for "
   "%s: %d\n", driver, err);
-- 
1.7.9.5

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


[PATCH 1/2] Helper macros used for replacing the use of VLAIS

2012-10-30 Thread Behan Webster
The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This new header file contains macros which can be used to
calculate the size and offset of variables in an allocated buffer of memory
taking into account alignment issues.

Signed-off-by: Behan Webster 
---
 include/linux/valign.h |   87 
 1 file changed, 87 insertions(+)
 create mode 100644 include/linux/valign.h

diff --git a/include/linux/valign.h b/include/linux/valign.h
new file mode 100644
index 000..b39381b
--- /dev/null
+++ b/include/linux/valign.h
@@ -0,0 +1,87 @@
+/*
+ * Variable alignment macros used to break up a larger chunk of memory into
+ * smaller variables. Meant to be used to replace the use of Variable Length
+ * Arrays In Structures (VLAIS)
+ *
+ *  Copyright (C) 2012 Behan Webster 
+ */
+
+#ifndef _VALIGN_H_
+#define _VALIGN_H_
+
+/**
+ * truncalign() - Align a memory address by truncation
+ * @num:   Address or size to align
+ * @padwidth:  Number of byte upon which to align
+ *
+ * Truncate an address or size to a particular memory alignment.
+ * Used by truncalign().
+ */
+#define truncalign(num, padwidth) ((long)(num) & ~((padwidth)-1))
+
+/**
+ * padalign() - Align a memory address by padding
+ * @num:   Address or size to align
+ * @padwidth:  Number of byte upon which to align
+ *
+ * Pad out an address or size to a particular memory alignment
+ * Used by paddedsize() and paddedstart().
+ */
+#define padalign(num, padwidth) \
+   truncalign((long)(num) + ((padwidth)-1), padwidth)
+
+/**
+ * paddedsize() - Calculate the size of an chunk of aligned memory
+ * @offset:Unaligned offset to the start of the chunk size being calculated
+ * @num:   The number of variables in the array of "type" (can be 1)
+ * @type:  The type of variables in the array
+ * @nexttype:  The type of the next variable in the large piece of memory
+ *
+ * Calculate the size that a variable (or array) will take as a part of a
+ * larger piece of memory.  Takes into account a potentially unaligned offset
+ * into the larger piece of allocated memory, the alignment of the variable
+ * type, and the alignement of the type of the variable to be used after that.
+ *
+ * Example: size_t l = paddedsize(1, 2, short, int);
+ *
+ * The example above would give you a padded size of 6 bytes: 2x 16-bit shorts,
+ * starting at 2 bytes into the buffer (the offset of 1 byte being padded out
+ * to 2 bytes) followed by 2 bytes of padding so that the next type (a 32-bit
+ * int) would be 32-bit aligned. looking like this:
+ *
+ *   0: O.SS SS.. 
+ *\-/ <-- 2 shorts + 2 bytes of padding = size of 6 bytes
+ *
+ * O = The offset
+ * . = Padding bytes
+ * S = 2 shorts
+ * i = int which will theoretically be next
+ */
+#define paddedsize(offset, num, type, nexttype) (padalign((offset) \
+   + (num) * sizeof(type), __alignof__(nexttype)) - (offset))
+
+/**
+ * paddedstart() - Calculate the start of a chunk of aligned memory
+ * @ptr:   Pointer from which to calculate the start of the chunk
+ * @offset:Offset from the ptr to the start of the chunk being calculated
+ * @type:  The type of variable in the chunk of memory
+ *
+ * Calculate the start address of a variable based on the offset from an
+ * address, aligned based on the type of the variable specified.
+ *
+ * Example: char *data = kmalloc(size, GFP_KERNEL);
+ *  long *var = paddedstart(data, 12, long);
+ *
+ * The example above on a 64-bit machine would return the equivalent of
+ * [16] since a long needs to be 8 byte aligned.
+ *
+ *   0:      
+ *  ^ <-- The start address of the long
+ * O = The offset
+ * . = Padding bytes
+ * L = The long
+ */
+#define paddedstart(ptr, offset, type) \
+   (type *)padalign((long)(ptr)+(offset), __alignof__(type))
+
+#endif
-- 
1.7.9.5

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


[PATCH 2/2] Remove VLAIS usage from gadget code

2012-10-30 Thread Behan Webster
The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This patch instead calculates offsets into the kmalloc-ed
memory buffer using macros from valign.h.

Signed-off-by: Behan Webster 
---
 drivers/usb/gadget/f_fs.c |  106 ++---
 1 file changed, 61 insertions(+), 45 deletions(-)

diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index 64c4ec1..ca6cacc 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -1875,6 +1876,15 @@ error:
return ret;
 }
 
+static void __ffs_init_stringtabs(struct usb_gadget_strings **stringtabs,
+   struct usb_gadget_strings *t, unsigned len)
+{
+   do {
+   *stringtabs++ = t++;
+   } while (--len);
+   *stringtabs = NULL;
+}
+
 static int __ffs_data_got_strings(struct ffs_data *ffs,
  char *const _data, size_t len)
 {
@@ -1911,31 +1921,26 @@ static int __ffs_data_got_strings(struct ffs_data *ffs,
 
/* Allocate everything in one chunk so there's less maintenance. */
{
-   struct {
-   struct usb_gadget_strings *stringtabs[lang_count + 1];
-   struct usb_gadget_strings stringtab[lang_count];
-   struct usb_string strings[lang_count*(needed_count+1)];
-   } *d;
-   unsigned i = 0;
-
-   d = kmalloc(sizeof *d, GFP_KERNEL);
+   int strtabslen = paddedsize(0, lang_count+1,
+   struct usb_gadget_strings *, struct usb_gadget_strings);
+   int strtablen = paddedsize(strtabslen, lang_count,
+   struct usb_gadget_strings, struct usb_string);
+   int strlen = paddedsize(strtabslen + strtablen,
+   lang_count*(needed_count+1), struct usb_string, int);
+
+   stringtabs = kmalloc(strtabslen + strtablen + strlen,
+   GFP_KERNEL);
if (unlikely(!d)) {
kfree(_data);
return -ENOMEM;
}
 
-   stringtabs = d->stringtabs;
-   t = d->stringtab;
-   i = lang_count;
-   do {
-   *stringtabs++ = t++;
-   } while (--i);
-   *stringtabs = NULL;
-
-   stringtabs = d->stringtabs;
-   t = d->stringtab;
-   s = d->strings;
+   t = paddedstart(stringtabs, strtabslen,
+   struct usb_gadget_strings);
+   s = paddedstart(t, strtablen, struct usb_string);
strings = s;
+
+   __ffs_init_stringtabs(stringtabs, t, lang_count);
}
 
/* For each language */
@@ -2209,17 +2214,23 @@ static int ffs_func_bind(struct usb_configuration *c,
 
int ret;
 
-   /* Make it a single chunk, less management later on */
-   struct {
-   struct ffs_ep eps[ffs->eps_count];
-   struct usb_descriptor_header
-   *fs_descs[full ? ffs->fs_descs_count + 1 : 0];
-   struct usb_descriptor_header
-   *hs_descs[high ? ffs->hs_descs_count + 1 : 0];
-   short inums[ffs->interfaces_count];
-   char raw_descs[high ? ffs->raw_descs_length
-   : ffs->raw_fs_descs_length];
-   } *data;
+   struct ffs_ep *eps;
+   struct usb_descriptor_header **fs_descs;
+   struct usb_descriptor_header **hs_descs;
+   short *inums;
+   char *raw_descs;
+
+   int epslen = paddedsize(0, ffs->eps_count,
+   struct ffs_ep, struct usb_descriptor_header);
+   int fsdlen = paddedsize(epslen, full ? ffs->fs_descs_count + 1 : 0,
+   struct usb_descriptor_header,
+   struct usb_descriptor_header);
+   int hsdlen = paddedsize(fsdlen, high ? ffs->hs_descs_count + 1 : 0,
+   struct usb_descriptor_header, short);
+   int inumlen = paddedsize(hsdlen, ffs->interfaces_count, short, char);
+   int rawlen = paddedsize(inumlen,
+   high ? ffs->raw_descs_length : ffs->raw_fs_descs_length,
+   char, int);
 
ENTER();
 
@@ -2227,21 +2238,28 @@ static int ffs_func_bind(struct usb_configuration *c,
if (unlikely(!(full | high)))
return -ENOTSUPP;
 
-   /* Allocate */
-   data = kmalloc(sizeof *data, GFP_KERNEL);
+   /* Allocate a single chunk, less management later on */
+   eps = kmalloc(epslen+fsdlen+hsdlen+inumlen+rawlen, GFP_KERNEL);
if (unlikely(!data))
return -EN

[PATCH 0/2] Removing the use of VLAIS from the Linux Kernel

2012-10-30 Thread Behan Webster
The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). The LLVMLinux Project is working towards the ability of
providing the Linux kernel developer the choice of using the Clang compiler
toolchain. This is a part of a series of patches which remove the use of VLAIS
from crypto code, dm-crypt, jbd2, libcrc32c, netfilter, and usb gadget. Other
patches to allow Clang to be used will follow.

Behan Webster (2):
  Helper macros used for replacing the use of VLAIS
  Remove VLAIS usage from gadget code

 drivers/usb/gadget/f_fs.c |  106 ++---
 include/linux/valign.h|   87 +
 2 files changed, 148 insertions(+), 45 deletions(-)
 create mode 100644 include/linux/valign.h

-- 
1.7.9.5

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


[PATCH 0/2] Removing the use of VLAIS from the Linux Kernel

2012-10-30 Thread Behan Webster
The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). The LLVMLinux Project is working towards the ability of
providing the Linux kernel developer the choice of using the Clang compiler
toolchain. This is a part of a series of patches which remove the use of VLAIS
from crypto code, dm-crypt, jbd2, libcrc32c, netfilter, and usb gadget. Other
patches to allow Clang to be used will follow.

Behan Webster (2):
  Helper macros used for replacing the use of VLAIS
  Remove VLAIS usage from gadget code

 drivers/usb/gadget/f_fs.c |  106 ++---
 include/linux/valign.h|   87 +
 2 files changed, 148 insertions(+), 45 deletions(-)
 create mode 100644 include/linux/valign.h

-- 
1.7.9.5

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


[PATCH 2/2] Remove VLAIS usage from gadget code

2012-10-30 Thread Behan Webster
The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This patch instead calculates offsets into the kmalloc-ed
memory buffer using macros from valign.h.

Signed-off-by: Behan Webster beh...@converseincode.com
---
 drivers/usb/gadget/f_fs.c |  106 ++---
 1 file changed, 61 insertions(+), 45 deletions(-)

diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index 64c4ec1..ca6cacc 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -22,6 +22,7 @@
 #include linux/pagemap.h
 #include linux/export.h
 #include linux/hid.h
+#include linux/valign.h
 #include asm/unaligned.h
 
 #include linux/usb/composite.h
@@ -1875,6 +1876,15 @@ error:
return ret;
 }
 
+static void __ffs_init_stringtabs(struct usb_gadget_strings **stringtabs,
+   struct usb_gadget_strings *t, unsigned len)
+{
+   do {
+   *stringtabs++ = t++;
+   } while (--len);
+   *stringtabs = NULL;
+}
+
 static int __ffs_data_got_strings(struct ffs_data *ffs,
  char *const _data, size_t len)
 {
@@ -1911,31 +1921,26 @@ static int __ffs_data_got_strings(struct ffs_data *ffs,
 
/* Allocate everything in one chunk so there's less maintenance. */
{
-   struct {
-   struct usb_gadget_strings *stringtabs[lang_count + 1];
-   struct usb_gadget_strings stringtab[lang_count];
-   struct usb_string strings[lang_count*(needed_count+1)];
-   } *d;
-   unsigned i = 0;
-
-   d = kmalloc(sizeof *d, GFP_KERNEL);
+   int strtabslen = paddedsize(0, lang_count+1,
+   struct usb_gadget_strings *, struct usb_gadget_strings);
+   int strtablen = paddedsize(strtabslen, lang_count,
+   struct usb_gadget_strings, struct usb_string);
+   int strlen = paddedsize(strtabslen + strtablen,
+   lang_count*(needed_count+1), struct usb_string, int);
+
+   stringtabs = kmalloc(strtabslen + strtablen + strlen,
+   GFP_KERNEL);
if (unlikely(!d)) {
kfree(_data);
return -ENOMEM;
}
 
-   stringtabs = d-stringtabs;
-   t = d-stringtab;
-   i = lang_count;
-   do {
-   *stringtabs++ = t++;
-   } while (--i);
-   *stringtabs = NULL;
-
-   stringtabs = d-stringtabs;
-   t = d-stringtab;
-   s = d-strings;
+   t = paddedstart(stringtabs, strtabslen,
+   struct usb_gadget_strings);
+   s = paddedstart(t, strtablen, struct usb_string);
strings = s;
+
+   __ffs_init_stringtabs(stringtabs, t, lang_count);
}
 
/* For each language */
@@ -2209,17 +2214,23 @@ static int ffs_func_bind(struct usb_configuration *c,
 
int ret;
 
-   /* Make it a single chunk, less management later on */
-   struct {
-   struct ffs_ep eps[ffs-eps_count];
-   struct usb_descriptor_header
-   *fs_descs[full ? ffs-fs_descs_count + 1 : 0];
-   struct usb_descriptor_header
-   *hs_descs[high ? ffs-hs_descs_count + 1 : 0];
-   short inums[ffs-interfaces_count];
-   char raw_descs[high ? ffs-raw_descs_length
-   : ffs-raw_fs_descs_length];
-   } *data;
+   struct ffs_ep *eps;
+   struct usb_descriptor_header **fs_descs;
+   struct usb_descriptor_header **hs_descs;
+   short *inums;
+   char *raw_descs;
+
+   int epslen = paddedsize(0, ffs-eps_count,
+   struct ffs_ep, struct usb_descriptor_header);
+   int fsdlen = paddedsize(epslen, full ? ffs-fs_descs_count + 1 : 0,
+   struct usb_descriptor_header,
+   struct usb_descriptor_header);
+   int hsdlen = paddedsize(fsdlen, high ? ffs-hs_descs_count + 1 : 0,
+   struct usb_descriptor_header, short);
+   int inumlen = paddedsize(hsdlen, ffs-interfaces_count, short, char);
+   int rawlen = paddedsize(inumlen,
+   high ? ffs-raw_descs_length : ffs-raw_fs_descs_length,
+   char, int);
 
ENTER();
 
@@ -2227,21 +2238,28 @@ static int ffs_func_bind(struct usb_configuration *c,
if (unlikely(!(full | high)))
return -ENOTSUPP;
 
-   /* Allocate */
-   data = kmalloc(sizeof *data, GFP_KERNEL);
+   /* Allocate a single chunk, less management later on */
+   eps = kmalloc(epslen+fsdlen+hsdlen+inumlen+rawlen, GFP_KERNEL

[PATCH 1/2] Helper macros used for replacing the use of VLAIS

2012-10-30 Thread Behan Webster
The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This new header file contains macros which can be used to
calculate the size and offset of variables in an allocated buffer of memory
taking into account alignment issues.

Signed-off-by: Behan Webster beh...@converseincode.com
---
 include/linux/valign.h |   87 
 1 file changed, 87 insertions(+)
 create mode 100644 include/linux/valign.h

diff --git a/include/linux/valign.h b/include/linux/valign.h
new file mode 100644
index 000..b39381b
--- /dev/null
+++ b/include/linux/valign.h
@@ -0,0 +1,87 @@
+/*
+ * Variable alignment macros used to break up a larger chunk of memory into
+ * smaller variables. Meant to be used to replace the use of Variable Length
+ * Arrays In Structures (VLAIS)
+ *
+ *  Copyright (C) 2012 Behan Webster beh...@conversincode.com
+ */
+
+#ifndef _VALIGN_H_
+#define _VALIGN_H_
+
+/**
+ * truncalign() - Align a memory address by truncation
+ * @num:   Address or size to align
+ * @padwidth:  Number of byte upon which to align
+ *
+ * Truncate an address or size to a particular memory alignment.
+ * Used by truncalign().
+ */
+#define truncalign(num, padwidth) ((long)(num)  ~((padwidth)-1))
+
+/**
+ * padalign() - Align a memory address by padding
+ * @num:   Address or size to align
+ * @padwidth:  Number of byte upon which to align
+ *
+ * Pad out an address or size to a particular memory alignment
+ * Used by paddedsize() and paddedstart().
+ */
+#define padalign(num, padwidth) \
+   truncalign((long)(num) + ((padwidth)-1), padwidth)
+
+/**
+ * paddedsize() - Calculate the size of an chunk of aligned memory
+ * @offset:Unaligned offset to the start of the chunk size being calculated
+ * @num:   The number of variables in the array of type (can be 1)
+ * @type:  The type of variables in the array
+ * @nexttype:  The type of the next variable in the large piece of memory
+ *
+ * Calculate the size that a variable (or array) will take as a part of a
+ * larger piece of memory.  Takes into account a potentially unaligned offset
+ * into the larger piece of allocated memory, the alignment of the variable
+ * type, and the alignement of the type of the variable to be used after that.
+ *
+ * Example: size_t l = paddedsize(1, 2, short, int);
+ *
+ * The example above would give you a padded size of 6 bytes: 2x 16-bit shorts,
+ * starting at 2 bytes into the buffer (the offset of 1 byte being padded out
+ * to 2 bytes) followed by 2 bytes of padding so that the next type (a 32-bit
+ * int) would be 32-bit aligned. looking like this:
+ *
+ *   0: O.SS SS.. 
+ *\-/ -- 2 shorts + 2 bytes of padding = size of 6 bytes
+ *
+ * O = The offset
+ * . = Padding bytes
+ * S = 2 shorts
+ * i = int which will theoretically be next
+ */
+#define paddedsize(offset, num, type, nexttype) (padalign((offset) \
+   + (num) * sizeof(type), __alignof__(nexttype)) - (offset))
+
+/**
+ * paddedstart() - Calculate the start of a chunk of aligned memory
+ * @ptr:   Pointer from which to calculate the start of the chunk
+ * @offset:Offset from the ptr to the start of the chunk being calculated
+ * @type:  The type of variable in the chunk of memory
+ *
+ * Calculate the start address of a variable based on the offset from an
+ * address, aligned based on the type of the variable specified.
+ *
+ * Example: char *data = kmalloc(size, GFP_KERNEL);
+ *  long *var = paddedstart(data, 12, long);
+ *
+ * The example above on a 64-bit machine would return the equivalent of
+ * buffer[16] since a long needs to be 8 byte aligned.
+ *
+ *   0:      
+ *  ^ -- The start address of the long
+ * O = The offset
+ * . = Padding bytes
+ * L = The long
+ */
+#define paddedstart(ptr, offset, type) \
+   (type *)padalign((long)(ptr)+(offset), __alignof__(type))
+
+#endif
-- 
1.7.9.5

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


[PATCH 2/2] Remove VLAIS usage from crypto/testmgr.c

2012-10-30 Thread Behan Webster
From: Jan-Simon Möller dl...@gmx.de

The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This patch instead allocates the appropriate amount of memory
using an char array.

Patch from series at
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120507/142707.html
by PaX Team.

Signed-off-by: Jan-Simon Möller dl...@gmx.de
Cc: pagee...@freemail.hu
Signed-off-by: Behan Webster beh...@converseincode.com
---
 crypto/testmgr.c |   23 +--
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 941d75c..5b7b3a6 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -1578,16 +1578,19 @@ static int alg_test_crc32c(const struct alg_test_desc 
*desc,
}
 
do {
-   struct {
-   struct shash_desc shash;
-   char ctx[crypto_shash_descsize(tfm)];
-   } sdesc;
-
-   sdesc.shash.tfm = tfm;
-   sdesc.shash.flags = 0;
-
-   *(u32 *)sdesc.ctx = le32_to_cpu(420553207);
-   err = crypto_shash_final(sdesc.shash, (u8 *)val);
+   char sdesc[sizeof(struct shash_desc)
+   + crypto_shash_descsize(tfm)
+   + CRYPTO_MINALIGN] CRYPTO_MINALIGN_ATTR;
+   struct shash_desc *shash = (struct shash_desc *)sdesc;
+   u32 *ctx = (u32 *)((unsigned long)(sdesc
+   + sizeof(struct shash_desc) + CRYPTO_MINALIGN - 1)
+~(CRYPTO_MINALIGN - 1));
+
+   shash-tfm = tfm;
+   shash-flags = 0;
+
+   *ctx = le32_to_cpu(420553207);
+   err = crypto_shash_final(shash, (u8 *)val);
if (err) {
printk(KERN_ERR alg: crc32c: Operation failed for 
   %s: %d\n, driver, err);
-- 
1.7.9.5

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


[PATCH 0/2] Removing the use of VLAIS from the Linux Kernel

2012-10-30 Thread Behan Webster
The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). The LLVMLinux Project is working towards the ability of
providing the Linux kernel developer the choice of using the Clang compiler
toolchain. This is a part of a series of patches which remove the use of VLAIS
from crypto code, dm-crypt, jbd2, libcrc32c, netfilter, and usb gadget. Other
patches to allow Clang to be used will follow.

Jan-Simon Möller (2):
  Remove VLAIS usage from crypto/hmac.c
  Remove VLAIS usage from crypto/testmgr.c

 crypto/hmac.c|   27 +--
 crypto/testmgr.c |   23 +--
 2 files changed, 26 insertions(+), 24 deletions(-)

-- 
1.7.9.5

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


[PATCH 1/2] Remove VLAIS usage from crypto/hmac.c

2012-10-30 Thread Behan Webster
From: Jan-Simon Möller dl...@gmx.de

The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This patch instead allocates the appropriate amount of memory
using an char array.

Patch from series at
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120507/142707.html
by PaX Team.

Signed-off-by: Jan-Simon Möller dl...@gmx.de
Cc: pagee...@freemail.hu
Signed-off-by: Behan Webster beh...@converseincode.com
---
 crypto/hmac.c |   27 +--
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/crypto/hmac.c b/crypto/hmac.c
index 8d9544c..1061255 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -52,20 +52,19 @@ static int hmac_setkey(struct crypto_shash *parent,
struct hmac_ctx *ctx = align_ptr(opad + ss,
 crypto_tfm_ctx_alignment());
struct crypto_shash *hash = ctx-hash;
-   struct {
-   struct shash_desc shash;
-   char ctx[crypto_shash_descsize(hash)];
-   } desc;
+   char desc[sizeof(struct shash_desc) + crypto_shash_descsize(hash)
+   + CRYPTO_MINALIGN] CRYPTO_MINALIGN_ATTR;
+   struct shash_desc *shash = (struct shash_desc *)desc;
unsigned int i;
 
-   desc.shash.tfm = hash;
-   desc.shash.flags = crypto_shash_get_flags(parent) 
-   CRYPTO_TFM_REQ_MAY_SLEEP;
+   shash-tfm = hash;
+   shash-flags = crypto_shash_get_flags(parent)
+CRYPTO_TFM_REQ_MAY_SLEEP;
 
if (keylen  bs) {
int err;
 
-   err = crypto_shash_digest(desc.shash, inkey, keylen, ipad);
+   err = crypto_shash_digest(shash, inkey, keylen, ipad);
if (err)
return err;
 
@@ -81,12 +80,12 @@ static int hmac_setkey(struct crypto_shash *parent,
opad[i] ^= 0x5c;
}
 
-   return crypto_shash_init(desc.shash) ?:
-  crypto_shash_update(desc.shash, ipad, bs) ?:
-  crypto_shash_export(desc.shash, ipad) ?:
-  crypto_shash_init(desc.shash) ?:
-  crypto_shash_update(desc.shash, opad, bs) ?:
-  crypto_shash_export(desc.shash, opad);
+   return crypto_shash_init(shash) ?:
+  crypto_shash_update(shash, ipad, bs) ?:
+  crypto_shash_export(shash, ipad) ?:
+  crypto_shash_init(shash) ?:
+  crypto_shash_update(shash, opad, bs) ?:
+  crypto_shash_export(shash, opad);
 }
 
 static int hmac_export(struct shash_desc *pdesc, void *out)
-- 
1.7.9.5

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


[PATCH 0/2] Removing the use of VLAIS from netfilter

2012-10-30 Thread Behan Webster
The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). The LLVMLinux Project is working towards the ability of
providing the Linux kernel developer the choice of using the Clang compiler
toolchain. This is a part of a series of patches which remove the use of VLAIS
from crypto code, dm-crypt, jbd2, libcrc32c, netfilter, and usb gadget. Other
patches to allow Clang to be used will follow.

Behan Webster (1):
  Helper macros used for replacing the use of VLAIS

Jan-Simon Möller (1):
  Remove VLAIS usage from netfilter

 include/linux/valign.h  |   87 +++
 net/netfilter/xt_repldata.h |   40 
 2 files changed, 111 insertions(+), 16 deletions(-)
 create mode 100644 include/linux/valign.h

-- 
1.7.9.5

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


[PATCH 1/2] Helper macros used for replacing the use of VLAIS

2012-10-30 Thread Behan Webster
The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This new header file contains macros which can be used to
calculate the size and offset of variables in an allocated buffer of memory
taking into account alignment issues.

Signed-off-by: Behan Webster beh...@converseincode.com
---
 include/linux/valign.h |   87 
 1 file changed, 87 insertions(+)
 create mode 100644 include/linux/valign.h

diff --git a/include/linux/valign.h b/include/linux/valign.h
new file mode 100644
index 000..b39381b
--- /dev/null
+++ b/include/linux/valign.h
@@ -0,0 +1,87 @@
+/*
+ * Variable alignment macros used to break up a larger chunk of memory into
+ * smaller variables. Meant to be used to replace the use of Variable Length
+ * Arrays In Structures (VLAIS)
+ *
+ *  Copyright (C) 2012 Behan Webster beh...@conversincode.com
+ */
+
+#ifndef _VALIGN_H_
+#define _VALIGN_H_
+
+/**
+ * truncalign() - Align a memory address by truncation
+ * @num:   Address or size to align
+ * @padwidth:  Number of byte upon which to align
+ *
+ * Truncate an address or size to a particular memory alignment.
+ * Used by truncalign().
+ */
+#define truncalign(num, padwidth) ((long)(num)  ~((padwidth)-1))
+
+/**
+ * padalign() - Align a memory address by padding
+ * @num:   Address or size to align
+ * @padwidth:  Number of byte upon which to align
+ *
+ * Pad out an address or size to a particular memory alignment
+ * Used by paddedsize() and paddedstart().
+ */
+#define padalign(num, padwidth) \
+   truncalign((long)(num) + ((padwidth)-1), padwidth)
+
+/**
+ * paddedsize() - Calculate the size of an chunk of aligned memory
+ * @offset:Unaligned offset to the start of the chunk size being calculated
+ * @num:   The number of variables in the array of type (can be 1)
+ * @type:  The type of variables in the array
+ * @nexttype:  The type of the next variable in the large piece of memory
+ *
+ * Calculate the size that a variable (or array) will take as a part of a
+ * larger piece of memory.  Takes into account a potentially unaligned offset
+ * into the larger piece of allocated memory, the alignment of the variable
+ * type, and the alignement of the type of the variable to be used after that.
+ *
+ * Example: size_t l = paddedsize(1, 2, short, int);
+ *
+ * The example above would give you a padded size of 6 bytes: 2x 16-bit shorts,
+ * starting at 2 bytes into the buffer (the offset of 1 byte being padded out
+ * to 2 bytes) followed by 2 bytes of padding so that the next type (a 32-bit
+ * int) would be 32-bit aligned. looking like this:
+ *
+ *   0: O.SS SS.. 
+ *\-/ -- 2 shorts + 2 bytes of padding = size of 6 bytes
+ *
+ * O = The offset
+ * . = Padding bytes
+ * S = 2 shorts
+ * i = int which will theoretically be next
+ */
+#define paddedsize(offset, num, type, nexttype) (padalign((offset) \
+   + (num) * sizeof(type), __alignof__(nexttype)) - (offset))
+
+/**
+ * paddedstart() - Calculate the start of a chunk of aligned memory
+ * @ptr:   Pointer from which to calculate the start of the chunk
+ * @offset:Offset from the ptr to the start of the chunk being calculated
+ * @type:  The type of variable in the chunk of memory
+ *
+ * Calculate the start address of a variable based on the offset from an
+ * address, aligned based on the type of the variable specified.
+ *
+ * Example: char *data = kmalloc(size, GFP_KERNEL);
+ *  long *var = paddedstart(data, 12, long);
+ *
+ * The example above on a 64-bit machine would return the equivalent of
+ * buffer[16] since a long needs to be 8 byte aligned.
+ *
+ *   0:      
+ *  ^ -- The start address of the long
+ * O = The offset
+ * . = Padding bytes
+ * L = The long
+ */
+#define paddedstart(ptr, offset, type) \
+   (type *)padalign((long)(ptr)+(offset), __alignof__(type))
+
+#endif
-- 
1.7.9.5

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


[PATCH 2/2] Remove VLAIS usage from netfilter

2012-10-30 Thread Behan Webster
From: Jan-Simon Möller dl...@gmx.de

The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This patch instead calculates offsets into the kmalloc-ed
memory buffer using macros from valign.h.

Patch from series at
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120507/142707.html
by PaX Team.

Signed-off-by: Jan-Simon Möller dl...@gmx.de
Cc: pagee...@freemail.hu
[Modified to use macros from valign.h]
Signed-off-by: Behan Webster beh...@converseincode.com
---
 net/netfilter/xt_repldata.h |   40 
 1 file changed, 24 insertions(+), 16 deletions(-)

diff --git a/net/netfilter/xt_repldata.h b/net/netfilter/xt_repldata.h
index 6efe4e5..d2b4232 100644
--- a/net/netfilter/xt_repldata.h
+++ b/net/netfilter/xt_repldata.h
@@ -5,31 +5,39 @@
  * they serve as the hanging-off data accessed through repl.data[].
  */
 
+#include linux/valign.h
+
 #define xt_alloc_initial_table(type, typ2) ({ \
unsigned int hook_mask = info-valid_hooks; \
unsigned int nhooks = hweight32(hook_mask); \
unsigned int bytes = 0, hooknum = 0, i = 0; \
-   struct { \
-   struct type##_replace repl; \
-   struct type##_standard entries[nhooks]; \
-   struct type##_error term; \
-   } *tbl = kzalloc(sizeof(*tbl), GFP_KERNEL); \
-   if (tbl == NULL) \
+   int replsize = paddedsize(0, 1, \
+   struct type##_replace, struct type##_standard); \
+   int entsize = paddedsize(replsize, nhooks, \
+   struct type##_standard, struct type##_error); \
+   int termsize = paddedsize(replsize+entsize, 1, \
+   struct type##_error, int); \
+   struct type##_replace *repl = kzalloc(replsize+entsize+termsize, \
+   GFP_KERNEL); \
+   if (repl == NULL) \
return NULL; \
-   strncpy(tbl-repl.name, info-name, sizeof(tbl-repl.name)); \
-   tbl-term = (struct type##_error)typ2##_ERROR_INIT;  \
-   tbl-repl.valid_hooks = hook_mask; \
-   tbl-repl.num_entries = nhooks + 1; \
-   tbl-repl.size = nhooks * sizeof(struct type##_standard) + \
-sizeof(struct type##_error); \
+   struct type##_standard *entries = paddedstart(repl, replsize, \
+   struct type##_standard); \
+   struct type##_error *term = paddedstart(entries, entsize, \
+   struct type##_error); \
+   strncpy(repl-name, info-name, sizeof(repl-name)); \
+   *term = (struct type##_error)typ2##_ERROR_INIT;  \
+   repl-valid_hooks = hook_mask; \
+   repl-num_entries = nhooks + 1; \
+   repl-size = entsize+termsize; \
for (; hook_mask != 0; hook_mask = 1, ++hooknum) { \
if (!(hook_mask  1)) \
continue; \
-   tbl-repl.hook_entry[hooknum] = bytes; \
-   tbl-repl.underflow[hooknum]  = bytes; \
-   tbl-entries[i++] = (struct type##_standard) \
+   repl-hook_entry[hooknum] = bytes; \
+   repl-underflow[hooknum]  = bytes; \
+   entries[i++] = (struct type##_standard) \
typ2##_STANDARD_INIT(NF_ACCEPT); \
bytes += sizeof(struct type##_standard); \
} \
-   tbl; \
+   repl; \
 })
-- 
1.7.9.5

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


[PATCH] Remove VLAIS usage from libcrc32c.c

2012-10-30 Thread Behan Webster
From: Jan-Simon Möller dl...@gmx.de

The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This patch instead allocates the appropriate amount of memory
using an char array.

Patch from series at
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120507/142707.html
by PaX Team.

Signed-off-by: Jan-Simon Möller dl...@gmx.de
Cc: pagee...@freemail.hu
Signed-off-by: Behan Webster beh...@converseincode.com
---
 lib/libcrc32c.c |   19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/lib/libcrc32c.c b/lib/libcrc32c.c
index 244f548..5d0bac8 100644
--- a/lib/libcrc32c.c
+++ b/lib/libcrc32c.c
@@ -41,20 +41,21 @@ static struct crypto_shash *tfm;
 
 u32 crc32c(u32 crc, const void *address, unsigned int length)
 {
-   struct {
-   struct shash_desc shash;
-   char ctx[crypto_shash_descsize(tfm)];
-   } desc;
+   char desc[sizeof(struct shash_desc) + crypto_shash_descsize(tfm)
+   + CRYPTO_MINALIGN] CRYPTO_MINALIGN_ATTR;
+   struct shash_desc *shash = (struct shash_desc *)desc;
+   u32 *ctx = (u32 *)((unsigned long)(desc + sizeof(struct shash_desc)
+   + CRYPTO_MINALIGN - 1)  ~(CRYPTO_MINALIGN - 1));
int err;
 
-   desc.shash.tfm = tfm;
-   desc.shash.flags = 0;
-   *(u32 *)desc.ctx = crc;
+   shash-tfm = tfm;
+   shash-flags = 0;
+   *ctx = crc;
 
-   err = crypto_shash_update(desc.shash, address, length);
+   err = crypto_shash_update(shash, address, length);
BUG_ON(err);
 
-   return *(u32 *)desc.ctx;
+   return *ctx;
 }
 
 EXPORT_SYMBOL(crc32c);
-- 
1.7.9.5

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


Re: [PATCH 1/2] Helper macros used for replacing the use of VLAIS

2012-10-30 Thread Behan Webster

On 12-10-30 03:20 PM, Greg KH wrote:

On Tue, Oct 30, 2012 at 02:25:19PM -0400, Behan Webster wrote:

The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This new header file contains macros which can be used to
calculate the size and offset of variables in an allocated buffer of memory
taking into account alignment issues.

Signed-off-by: Behan Webster beh...@converseincode.com
---
  include/linux/valign.h |   87 
  1 file changed, 87 insertions(+)
  create mode 100644 include/linux/valign.h

You sent the same patch here, to two different trees (usb and
networking).  That's not good, what happens if they both apply them?

Good point. My mistake.

People in both subsystems needed to see the patch which is why I sent them.

What would have been a better approach? And how can I fix this?

Behan

--
Behan Webster
beh...@converseincode.com

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


[PATCH V2 0/3] Removing the use of VLAIS from USB Gadget and netfilter

2012-10-30 Thread Behan Webster
This is a V2 version of the patch set I previously sent out. Since the use of a
new valign.h file spans both the USB and netfilter subsystems, I should have
sent out all 3 patches to both trees at once. Assuming all is well, hopefully
both subsystems can cooperate to get these patches in without causing
conflicts.

The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). The LLVMLinux Project is working towards the ability of
providing the Linux kernel developer the choice of using the Clang compiler
toolchain. This is a part of a series of patches which remove the use of VLAIS
from crypto code, dm-crypt, jbd2, libcrc32c, netfilter, and usb gadget. Other
patches to allow Clang to be used to compile the Linux kernel will follow.

Behan Webster (2):
  Helper macros used for replacing the use of VLAIS
  Remove VLAIS usage from gadget code

Jan-Simon Möller (1):
  Remove VLAIS usage from netfilter

 drivers/usb/gadget/f_fs.c   |  106 +--
 include/linux/valign.h  |   87 +++
 net/netfilter/xt_repldata.h |   40 +---
 3 files changed, 172 insertions(+), 61 deletions(-)
 create mode 100644 include/linux/valign.h

-- 
1.7.9.5

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


[PATCH V2 3/3] Remove VLAIS usage from netfilter

2012-10-30 Thread Behan Webster
From: Jan-Simon Möller dl...@gmx.de

The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This patch instead calculates offsets into the kmalloc-ed
memory buffer using macros from valign.h.

Patch from series at
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120507/142707.html
by PaX Team.

Signed-off-by: Jan-Simon Möller dl...@gmx.de
Cc: pagee...@freemail.hu
[Modified to use macros from valign.h]
Signed-off-by: Behan Webster beh...@converseincode.com
---
 net/netfilter/xt_repldata.h |   40 
 1 file changed, 24 insertions(+), 16 deletions(-)

diff --git a/net/netfilter/xt_repldata.h b/net/netfilter/xt_repldata.h
index 6efe4e5..d2b4232 100644
--- a/net/netfilter/xt_repldata.h
+++ b/net/netfilter/xt_repldata.h
@@ -5,31 +5,39 @@
  * they serve as the hanging-off data accessed through repl.data[].
  */
 
+#include linux/valign.h
+
 #define xt_alloc_initial_table(type, typ2) ({ \
unsigned int hook_mask = info-valid_hooks; \
unsigned int nhooks = hweight32(hook_mask); \
unsigned int bytes = 0, hooknum = 0, i = 0; \
-   struct { \
-   struct type##_replace repl; \
-   struct type##_standard entries[nhooks]; \
-   struct type##_error term; \
-   } *tbl = kzalloc(sizeof(*tbl), GFP_KERNEL); \
-   if (tbl == NULL) \
+   int replsize = paddedsize(0, 1, \
+   struct type##_replace, struct type##_standard); \
+   int entsize = paddedsize(replsize, nhooks, \
+   struct type##_standard, struct type##_error); \
+   int termsize = paddedsize(replsize+entsize, 1, \
+   struct type##_error, int); \
+   struct type##_replace *repl = kzalloc(replsize+entsize+termsize, \
+   GFP_KERNEL); \
+   if (repl == NULL) \
return NULL; \
-   strncpy(tbl-repl.name, info-name, sizeof(tbl-repl.name)); \
-   tbl-term = (struct type##_error)typ2##_ERROR_INIT;  \
-   tbl-repl.valid_hooks = hook_mask; \
-   tbl-repl.num_entries = nhooks + 1; \
-   tbl-repl.size = nhooks * sizeof(struct type##_standard) + \
-sizeof(struct type##_error); \
+   struct type##_standard *entries = paddedstart(repl, replsize, \
+   struct type##_standard); \
+   struct type##_error *term = paddedstart(entries, entsize, \
+   struct type##_error); \
+   strncpy(repl-name, info-name, sizeof(repl-name)); \
+   *term = (struct type##_error)typ2##_ERROR_INIT;  \
+   repl-valid_hooks = hook_mask; \
+   repl-num_entries = nhooks + 1; \
+   repl-size = entsize+termsize; \
for (; hook_mask != 0; hook_mask = 1, ++hooknum) { \
if (!(hook_mask  1)) \
continue; \
-   tbl-repl.hook_entry[hooknum] = bytes; \
-   tbl-repl.underflow[hooknum]  = bytes; \
-   tbl-entries[i++] = (struct type##_standard) \
+   repl-hook_entry[hooknum] = bytes; \
+   repl-underflow[hooknum]  = bytes; \
+   entries[i++] = (struct type##_standard) \
typ2##_STANDARD_INIT(NF_ACCEPT); \
bytes += sizeof(struct type##_standard); \
} \
-   tbl; \
+   repl; \
 })
-- 
1.7.9.5

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


[PATCH V2 2/3] Remove VLAIS usage from gadget code

2012-10-30 Thread Behan Webster
The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This patch instead calculates offsets into the kmalloc-ed
memory buffer using macros from valign.h.

Signed-off-by: Behan Webster beh...@converseincode.com
---
 drivers/usb/gadget/f_fs.c |  106 ++---
 1 file changed, 61 insertions(+), 45 deletions(-)

diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index 64c4ec1..ca6cacc 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -22,6 +22,7 @@
 #include linux/pagemap.h
 #include linux/export.h
 #include linux/hid.h
+#include linux/valign.h
 #include asm/unaligned.h
 
 #include linux/usb/composite.h
@@ -1875,6 +1876,15 @@ error:
return ret;
 }
 
+static void __ffs_init_stringtabs(struct usb_gadget_strings **stringtabs,
+   struct usb_gadget_strings *t, unsigned len)
+{
+   do {
+   *stringtabs++ = t++;
+   } while (--len);
+   *stringtabs = NULL;
+}
+
 static int __ffs_data_got_strings(struct ffs_data *ffs,
  char *const _data, size_t len)
 {
@@ -1911,31 +1921,26 @@ static int __ffs_data_got_strings(struct ffs_data *ffs,
 
/* Allocate everything in one chunk so there's less maintenance. */
{
-   struct {
-   struct usb_gadget_strings *stringtabs[lang_count + 1];
-   struct usb_gadget_strings stringtab[lang_count];
-   struct usb_string strings[lang_count*(needed_count+1)];
-   } *d;
-   unsigned i = 0;
-
-   d = kmalloc(sizeof *d, GFP_KERNEL);
+   int strtabslen = paddedsize(0, lang_count+1,
+   struct usb_gadget_strings *, struct usb_gadget_strings);
+   int strtablen = paddedsize(strtabslen, lang_count,
+   struct usb_gadget_strings, struct usb_string);
+   int strlen = paddedsize(strtabslen + strtablen,
+   lang_count*(needed_count+1), struct usb_string, int);
+
+   stringtabs = kmalloc(strtabslen + strtablen + strlen,
+   GFP_KERNEL);
if (unlikely(!d)) {
kfree(_data);
return -ENOMEM;
}
 
-   stringtabs = d-stringtabs;
-   t = d-stringtab;
-   i = lang_count;
-   do {
-   *stringtabs++ = t++;
-   } while (--i);
-   *stringtabs = NULL;
-
-   stringtabs = d-stringtabs;
-   t = d-stringtab;
-   s = d-strings;
+   t = paddedstart(stringtabs, strtabslen,
+   struct usb_gadget_strings);
+   s = paddedstart(t, strtablen, struct usb_string);
strings = s;
+
+   __ffs_init_stringtabs(stringtabs, t, lang_count);
}
 
/* For each language */
@@ -2209,17 +2214,23 @@ static int ffs_func_bind(struct usb_configuration *c,
 
int ret;
 
-   /* Make it a single chunk, less management later on */
-   struct {
-   struct ffs_ep eps[ffs-eps_count];
-   struct usb_descriptor_header
-   *fs_descs[full ? ffs-fs_descs_count + 1 : 0];
-   struct usb_descriptor_header
-   *hs_descs[high ? ffs-hs_descs_count + 1 : 0];
-   short inums[ffs-interfaces_count];
-   char raw_descs[high ? ffs-raw_descs_length
-   : ffs-raw_fs_descs_length];
-   } *data;
+   struct ffs_ep *eps;
+   struct usb_descriptor_header **fs_descs;
+   struct usb_descriptor_header **hs_descs;
+   short *inums;
+   char *raw_descs;
+
+   int epslen = paddedsize(0, ffs-eps_count,
+   struct ffs_ep, struct usb_descriptor_header);
+   int fsdlen = paddedsize(epslen, full ? ffs-fs_descs_count + 1 : 0,
+   struct usb_descriptor_header,
+   struct usb_descriptor_header);
+   int hsdlen = paddedsize(fsdlen, high ? ffs-hs_descs_count + 1 : 0,
+   struct usb_descriptor_header, short);
+   int inumlen = paddedsize(hsdlen, ffs-interfaces_count, short, char);
+   int rawlen = paddedsize(inumlen,
+   high ? ffs-raw_descs_length : ffs-raw_fs_descs_length,
+   char, int);
 
ENTER();
 
@@ -2227,21 +2238,28 @@ static int ffs_func_bind(struct usb_configuration *c,
if (unlikely(!(full | high)))
return -ENOTSUPP;
 
-   /* Allocate */
-   data = kmalloc(sizeof *data, GFP_KERNEL);
+   /* Allocate a single chunk, less management later on */
+   eps = kmalloc(epslen+fsdlen+hsdlen+inumlen+rawlen, GFP_KERNEL

[PATCH V2 1/3] Helper macros used for replacing the use of VLAIS

2012-10-30 Thread Behan Webster
The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
precludes the use of compilers which don't implement VLAIS (for instance the
Clang compiler). This new header file contains macros which can be used to
calculate the size and offset of variables in an allocated buffer of memory
taking into account alignment issues.

Signed-off-by: Behan Webster beh...@converseincode.com
---
 include/linux/valign.h |   87 
 1 file changed, 87 insertions(+)
 create mode 100644 include/linux/valign.h

diff --git a/include/linux/valign.h b/include/linux/valign.h
new file mode 100644
index 000..b39381b
--- /dev/null
+++ b/include/linux/valign.h
@@ -0,0 +1,87 @@
+/*
+ * Variable alignment macros used to break up a larger chunk of memory into
+ * smaller variables. Meant to be used to replace the use of Variable Length
+ * Arrays In Structures (VLAIS)
+ *
+ *  Copyright (C) 2012 Behan Webster beh...@conversincode.com
+ */
+
+#ifndef _VALIGN_H_
+#define _VALIGN_H_
+
+/**
+ * truncalign() - Align a memory address by truncation
+ * @num:   Address or size to align
+ * @padwidth:  Number of byte upon which to align
+ *
+ * Truncate an address or size to a particular memory alignment.
+ * Used by truncalign().
+ */
+#define truncalign(num, padwidth) ((long)(num)  ~((padwidth)-1))
+
+/**
+ * padalign() - Align a memory address by padding
+ * @num:   Address or size to align
+ * @padwidth:  Number of byte upon which to align
+ *
+ * Pad out an address or size to a particular memory alignment
+ * Used by paddedsize() and paddedstart().
+ */
+#define padalign(num, padwidth) \
+   truncalign((long)(num) + ((padwidth)-1), padwidth)
+
+/**
+ * paddedsize() - Calculate the size of an chunk of aligned memory
+ * @offset:Unaligned offset to the start of the chunk size being calculated
+ * @num:   The number of variables in the array of type (can be 1)
+ * @type:  The type of variables in the array
+ * @nexttype:  The type of the next variable in the large piece of memory
+ *
+ * Calculate the size that a variable (or array) will take as a part of a
+ * larger piece of memory.  Takes into account a potentially unaligned offset
+ * into the larger piece of allocated memory, the alignment of the variable
+ * type, and the alignement of the type of the variable to be used after that.
+ *
+ * Example: size_t l = paddedsize(1, 2, short, int);
+ *
+ * The example above would give you a padded size of 6 bytes: 2x 16-bit shorts,
+ * starting at 2 bytes into the buffer (the offset of 1 byte being padded out
+ * to 2 bytes) followed by 2 bytes of padding so that the next type (a 32-bit
+ * int) would be 32-bit aligned. looking like this:
+ *
+ *   0: O.SS SS.. 
+ *\-/ -- 2 shorts + 2 bytes of padding = size of 6 bytes
+ *
+ * O = The offset
+ * . = Padding bytes
+ * S = 2 shorts
+ * i = int which will theoretically be next
+ */
+#define paddedsize(offset, num, type, nexttype) (padalign((offset) \
+   + (num) * sizeof(type), __alignof__(nexttype)) - (offset))
+
+/**
+ * paddedstart() - Calculate the start of a chunk of aligned memory
+ * @ptr:   Pointer from which to calculate the start of the chunk
+ * @offset:Offset from the ptr to the start of the chunk being calculated
+ * @type:  The type of variable in the chunk of memory
+ *
+ * Calculate the start address of a variable based on the offset from an
+ * address, aligned based on the type of the variable specified.
+ *
+ * Example: char *data = kmalloc(size, GFP_KERNEL);
+ *  long *var = paddedstart(data, 12, long);
+ *
+ * The example above on a 64-bit machine would return the equivalent of
+ * buffer[16] since a long needs to be 8 byte aligned.
+ *
+ *   0:      
+ *  ^ -- The start address of the long
+ * O = The offset
+ * . = Padding bytes
+ * L = The long
+ */
+#define paddedstart(ptr, offset, type) \
+   (type *)padalign((long)(ptr)+(offset), __alignof__(type))
+
+#endif
-- 
1.7.9.5

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


<    1   2   3