--- /dev/null
+#ifndef __LICENSE_H
+#define __LICENSE_H
+
+static inline int license_is_gpl_compatible(const char *license)
+{
+       return (strcmp(license, "GPL") == 0
+               || strcmp(license, "GPL v2") == 0
+               || strcmp(license, "GPL and additional rights") == 0
+               || strcmp(license, "Dual BSD/GPL") == 0
+               || strcmp(license, "Dual MIT/GPL") == 0
+               || strcmp(license, "Dual MPL/GPL") == 0);
+}
+
+#endif
 
 #include <asm/uaccess.h>
 #include <asm/semaphore.h>
 #include <asm/cacheflush.h>
+#include <linux/license.h>
 
 #if 0
 #define DEBUGP printk
        }
 }
 
-static inline int license_is_gpl_compatible(const char *license)
-{
-       return (strcmp(license, "GPL") == 0
-               || strcmp(license, "GPL v2") == 0
-               || strcmp(license, "GPL and additional rights") == 0
-               || strcmp(license, "Dual BSD/GPL") == 0
-               || strcmp(license, "Dual MIT/GPL") == 0
-               || strcmp(license, "Dual MPL/GPL") == 0);
-}
-
 static void set_license(struct module *mod, const char *license)
 {
        if (!license)
 
 
 #include <ctype.h>
 #include "modpost.h"
+#include "../../include/linux/license.h"
 
 /* Are we using CONFIG_MODVERSIONS? */
 int modversions = 0;
 
        /* add to list */
        mod->name = p;
+       mod->gpl_compatible = -1;
        mod->next = modules;
        modules = mod;
 
        return string;
 }
 
-static char *get_modinfo(void *modinfo, unsigned long modinfo_len,
-                        const char *tag)
+static char *get_next_modinfo(void *modinfo, unsigned long modinfo_len,
+                             const char *tag, char *info)
 {
        char *p;
        unsigned int taglen = strlen(tag);
        unsigned long size = modinfo_len;
 
+       if (info) {
+               size -= info - (char *)modinfo;
+               modinfo = next_string(info, &size);
+       }
+
        for (p = modinfo; p; p = next_string(p, &size)) {
                if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
                        return p + taglen + 1;
        return NULL;
 }
 
+static char *get_modinfo(void *modinfo, unsigned long modinfo_len,
+                        const char *tag)
+
+{
+       return get_next_modinfo(modinfo, modinfo_len, tag, NULL);
+}
+
 /**
  * Test if string s ends in string sub
  * return 0 if match
 {
        const char *symname;
        char *version;
+       char *license;
        struct module *mod;
        struct elf_info info = { };
        Elf_Sym *sym;
                mod->skip = 1;
        }
 
+       license = get_modinfo(info.modinfo, info.modinfo_len, "license");
+       while (license) {
+               if (license_is_gpl_compatible(license))
+                       mod->gpl_compatible = 1;
+               else {
+                       mod->gpl_compatible = 0;
+                       break;
+               }
+               license = get_next_modinfo(info.modinfo, info.modinfo_len,
+                                          "license", license);
+       }
+
        for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
                symname = info.strtab + sym->st_name;
 
        buf->pos += len;
 }
 
+void check_license(struct module *mod)
+{
+       struct symbol *s, *exp;
+
+       for (s = mod->unres; s; s = s->next) {
+               if (mod->gpl_compatible == 1) {
+                       /* GPL-compatible modules may use all symbols */
+                       continue;
+               }
+               exp = find_symbol(s->name);
+               if (!exp || exp->module == mod)
+                       continue;
+               const char *basename = strrchr(mod->name, '/');
+               if (basename)
+                       basename++;
+               switch (exp->export) {
+                       case export_gpl:
+                               fatal("modpost: GPL-incompatible module %s "
+                                     "uses GPL-only symbol '%s'\n",
+                                basename ? basename : mod->name,
+                               exp->name);
+                               break;
+                       case export_gpl_future:
+                               warn("modpost: GPL-incompatible module %s "
+                                     "uses future GPL-only symbol '%s'\n",
+                                     basename ? basename : mod->name,
+                                     exp->name);
+                               break;
+                       case export_plain: /* ignore */ break;
+                       case export_unknown: /* ignore */ break;
+               }
+        }
+}
+
 /**
  * Header for the generated file
  **/
                read_symbols(argv[optind++]);
        }
 
+       for (mod = modules; mod; mod = mod->next) {
+               if (mod->skip)
+                       continue;
+               check_license(mod);
+       }
+
        for (mod = modules; mod; mod = mod->next) {
                if (mod->skip)
                        continue;