dfa_free(dfa);
 }
 
+
+
+/**
+ * remap_data16_to_data32 - remap u16 @old table to a u32 based table
+ * @old: table to remap
+ *
+ * Returns: new table with u32 entries instead of u16.
+ *
+ * Note: will free @old so caller does not have to
+ */
+static struct table_header *remap_data16_to_data32(struct table_header *old)
+{
+       struct table_header *new;
+       size_t tsize;
+       u32 i;
+
+       tsize = table_size(old->td_lolen, YYTD_DATA32);
+       new = kvzalloc(tsize, GFP_KERNEL);
+       if (!new) {
+               kvfree(old);
+               return NULL;
+       }
+       new->td_id = old->td_id;
+       new->td_flags = YYTD_DATA32;
+       new->td_lolen = old->td_lolen;
+
+       for (i = 0; i < old->td_lolen; i++)
+               TABLE_DATAU32(new)[i] = (u32) TABLE_DATAU16(old)[i];
+
+       kvfree(old);
+       if (is_vmalloc_addr(new))
+               vm_unmap_aliases();
+
+       return new;
+}
+
 /**
  * aa_dfa_unpack - unpack the binary tables of a serialized dfa
  * @blob: aligned serialized stream of data to unpack  (NOT NULL)
                case YYTD_ID_DEF:
                case YYTD_ID_NXT:
                case YYTD_ID_CHK:
-                       if (table->td_flags != YYTD_DATA16)
+                       if (!(table->td_flags == YYTD_DATA16 ||
+                             table->td_flags == YYTD_DATA32)) {
                                goto fail;
+                       }
                        break;
                case YYTD_ID_EC:
                        if (table->td_flags != YYTD_DATA8)
                dfa->tables[table->td_id] = table;
                data += table_size(table->td_lolen, table->td_flags);
                size -= table_size(table->td_lolen, table->td_flags);
+
+               /*
+                * this remapping has to be done after incrementing data above
+                * for now straight remap, later have dfa support both
+                */
+               switch (table->td_id) {
+               case YYTD_ID_DEF:
+               case YYTD_ID_NXT:
+               case YYTD_ID_CHK:
+                       if (table->td_flags == YYTD_DATA16) {
+                               table = remap_data16_to_data32(table);
+                               if (!table)
+                                       goto fail;
+                       }
+                       dfa->tables[table->td_id] = table;
+                       break;
+               }
                table = NULL;
        }
        error = verify_table_headers(dfa->tables, flags);
 aa_state_t aa_dfa_match_len(struct aa_dfa *dfa, aa_state_t start,
                            const char *str, int len)
 {
-       u16 *def = DEFAULT_TABLE(dfa);
+       u32 *def = DEFAULT_TABLE(dfa);
        u32 *base = BASE_TABLE(dfa);
-       u16 *next = NEXT_TABLE(dfa);
-       u16 *check = CHECK_TABLE(dfa);
+       u32 *next = NEXT_TABLE(dfa);
+       u32 *check = CHECK_TABLE(dfa);
        aa_state_t state = start;
 
        if (state == DFA_NOMATCH)
  */
 aa_state_t aa_dfa_match(struct aa_dfa *dfa, aa_state_t start, const char *str)
 {
-       u16 *def = DEFAULT_TABLE(dfa);
+       u32 *def = DEFAULT_TABLE(dfa);
        u32 *base = BASE_TABLE(dfa);
-       u16 *next = NEXT_TABLE(dfa);
-       u16 *check = CHECK_TABLE(dfa);
+       u32 *next = NEXT_TABLE(dfa);
+       u32 *check = CHECK_TABLE(dfa);
        aa_state_t state = start;
 
        if (state == DFA_NOMATCH)
  */
 aa_state_t aa_dfa_next(struct aa_dfa *dfa, aa_state_t state, const char c)
 {
-       u16 *def = DEFAULT_TABLE(dfa);
+       u32 *def = DEFAULT_TABLE(dfa);
        u32 *base = BASE_TABLE(dfa);
-       u16 *next = NEXT_TABLE(dfa);
-       u16 *check = CHECK_TABLE(dfa);
+       u32 *next = NEXT_TABLE(dfa);
+       u32 *check = CHECK_TABLE(dfa);
 
        /* current state is <state>, matching character *str */
        if (dfa->tables[YYTD_ID_EC]) {
 
 aa_state_t aa_dfa_outofband_transition(struct aa_dfa *dfa, aa_state_t state)
 {
-       u16 *def = DEFAULT_TABLE(dfa);
+       u32 *def = DEFAULT_TABLE(dfa);
        u32 *base = BASE_TABLE(dfa);
-       u16 *next = NEXT_TABLE(dfa);
-       u16 *check = CHECK_TABLE(dfa);
+       u32 *next = NEXT_TABLE(dfa);
+       u32 *check = CHECK_TABLE(dfa);
        u32 b = (base)[(state)];
 
        if (!(b & MATCH_FLAG_OOB_TRANSITION))
 aa_state_t aa_dfa_match_until(struct aa_dfa *dfa, aa_state_t start,
                                const char *str, const char **retpos)
 {
-       u16 *def = DEFAULT_TABLE(dfa);
+       u32 *def = DEFAULT_TABLE(dfa);
        u32 *base = BASE_TABLE(dfa);
-       u16 *next = NEXT_TABLE(dfa);
-       u16 *check = CHECK_TABLE(dfa);
+       u32 *next = NEXT_TABLE(dfa);
+       u32 *check = CHECK_TABLE(dfa);
        u32 *accept = ACCEPT_TABLE(dfa);
        aa_state_t state = start, pos;
 
 aa_state_t aa_dfa_matchn_until(struct aa_dfa *dfa, aa_state_t start,
                                 const char *str, int n, const char **retpos)
 {
-       u16 *def = DEFAULT_TABLE(dfa);
+       u32 *def = DEFAULT_TABLE(dfa);
        u32 *base = BASE_TABLE(dfa);
-       u16 *next = NEXT_TABLE(dfa);
-       u16 *check = CHECK_TABLE(dfa);
+       u32 *next = NEXT_TABLE(dfa);
+       u32 *check = CHECK_TABLE(dfa);
        u32 *accept = ACCEPT_TABLE(dfa);
        aa_state_t state = start, pos;
 
                                 const char *str, struct match_workbuf *wb,
                                 unsigned int *count)
 {
-       u16 *def = DEFAULT_TABLE(dfa);
+       u32 *def = DEFAULT_TABLE(dfa);
        u32 *base = BASE_TABLE(dfa);
-       u16 *next = NEXT_TABLE(dfa);
-       u16 *check = CHECK_TABLE(dfa);
+       u32 *next = NEXT_TABLE(dfa);
+       u32 *check = CHECK_TABLE(dfa);
        aa_state_t state = start, pos;
 
        AA_BUG(!dfa);