diff --git a/help.c b/help.c
index c9ae57e..c5eba7e 100755
--- a/help.c
+++ b/help.c
@@ -4495,7 +4495,7 @@ NULL
 char *help_mod[] = {
 "mod",
 "module information and loading of symbols and debugging data",
-"-s module [objfile] | -d module | -S [directory] | -D | -r | -R | -o | -g",
+"-s module [objfile] | -d module | -S [directory] | -D | -T | -r | -R | -o | -g",
 "  With no arguments, this command displays basic information of the currently",
 "  installed modules, consisting of the module address, name, size, the",
 "  object file name (if known), and whether the module was compiled with",
@@ -4547,6 +4547,7 @@ char *help_mod[] = {
 "                       argument is appended, then the search will be restricted",
 "                       to that directory.",
 "                   -D  Deletes the symbolic and debugging data of all modules.",
+"                   -T  Shows each module's taints flags (if supported).",
 "                   -r  Passes the -readnow flag to the embedded gdb module,",
 "                       which will override the two-stage strategy that it uses",
 "                       for reading symbol tables from module object files.",
@@ -4673,6 +4674,21 @@ char *help_mod[] = {
 "    c806e000  autofs       9316  (not loaded)",
 "    c8072000  nfsd       151896  (not loaded)",
 "    c80a1000  mdacon       3556  (not loaded)",
+" ",
+"  Display the taints flags for each module on kernels which support the",
+"  tnts[] array:",
+" ",
+"    %s> mod -T",
+"     NAME                 TAINT",
+"     dm_mod               G",
+"     scsi_tgt             G",
+"     serio_raw            G",
+"     dm_log               G",
+"     ata_generic          G",
+"     qla2xxx              P(U)",
+"     dm_region_hash       G",
+"     enclosure            G",
+"     pata_acpi            G",
 NULL               
 };
 
diff --git a/kernel.c b/kernel.c
index 2dac4ed..7b20247 100755
--- a/kernel.c
+++ b/kernel.c
@@ -22,6 +22,8 @@
 #include <ctype.h>
 
 static void do_module_cmd(ulong, char *, ulong, char *, char *);
+static void show_module_taint(void);
+static int is_module_taint(struct load_module *, char *, int *);
 static char *find_module_objfile(char *, char *, char *);
 static char *module_objfile_search(char *, char *, char *);
 static char *get_loadavg(char *);
@@ -3220,6 +3222,7 @@ irregularity:
 #define DELETE_ALL_MODULE_SYMBOLS     (5)
 #define REMOTE_MODULE_SAVE_MSG        (6)
 #define REINIT_MODULES                (7)
+#define LIST_ALL_MODULE_TAINT	       (8)
 
 void
 cmd_mod(void)
@@ -3294,7 +3297,7 @@ cmd_mod(void)
 	address = 0;
 	flag = LIST_MODULE_HDR;
 
-        while ((c = getopt(argcnt, args, "Rd:Ds:So")) != EOF) {
+        while ((c = getopt(argcnt, args, "Rd:Ds:SoTt:")) != EOF) {
                 switch(c)
 		{
                 case 'R':
@@ -3365,6 +3368,13 @@ cmd_mod(void)
 				cmd_usage(pc->curcmd, SYNOPSIS);
 			break;
 
+		case 'T':
+                        if (flag)
+				cmd_usage(pc->curcmd, SYNOPSIS);
+			else
+				flag = LIST_ALL_MODULE_TAINT;
+			break;
+
 		default:
 			argerrs++;
 			break;
@@ -3485,6 +3495,114 @@ check_specified_module_tree(char *module, char *gdb_buffer)
 	return retval;
 }
 
+int
+is_module_taint(struct load_module *lm, char *buf, int *maxtnts_len)
+{
+	int gpgsig_ok;
+	struct syment *sp = NULL;
+	ulong taints, tnts;
+	uint tnt_size;
+	ulong *taintsp;
+	uint8_t tnt_bit;
+	char tnt_true, tnt_false;
+	uint i, bx = 0;
+	int found = FALSE;
+
+	tnt_size = STRUCT_SIZE("struct tnt");
+	sp = symbol_search("tnts");
+
+	tnts = sp->value;
+
+	if (MEMBER_EXISTS("module", "taints")) {
+		readmem(lm->module_struct + MEMBER_OFFSET("module", "taints"),
+			KVADDR, &taints, sizeof(ulong), "module taints",
+			FAULT_ON_ERROR);
+
+		taintsp = &taints;
+
+		if (taints) {
+			for (i = 0; i < (get_array_length("tnts", NULL, 0)*tnt_size); i += tnt_size) {
+				readmem((tnts + i) + MEMBER_OFFSET("tnt", "bit"),
+					KVADDR, &tnt_bit, sizeof(uint8_t), "tnt bit",
+					FAULT_ON_ERROR);
+
+				if (NUM_IN_BITMAP(taintsp, tnt_bit)) {
+					readmem((tnts + i) + MEMBER_OFFSET("tnt", "true"),
+						KVADDR, &tnt_true, sizeof(char), "tnt true",
+						FAULT_ON_ERROR);
+					buf[bx++] = tnt_true;
+					found = TRUE;
+				} else {
+					readmem((tnts + i) + MEMBER_OFFSET("tnt", "false"),
+						KVADDR, &tnt_false, sizeof(char), "tnt false",
+						FAULT_ON_ERROR);
+
+					if (tnt_false != ' ' && tnt_false != '-') {
+						buf[bx++] = tnt_false;
+						found = TRUE;
+					}
+				}
+
+			}
+		}
+	}
+
+	if (MEMBER_EXISTS("module", "gpgsig_ok")) {
+		readmem(lm->module_struct + MEMBER_OFFSET("module", "gpgsig_ok"),
+			KVADDR, &gpgsig_ok, sizeof(int), "module gpgsig_ok",
+				FAULT_ON_ERROR);
+
+		if (!gpgsig_ok) {
+			buf[bx++] = '(';
+			buf[bx++] = 'U';
+			buf[bx++] = ')';
+			found = TRUE;
+		}
+	}
+	buf[bx++] = '\0';
+	*maxtnts_len = bx;
+	return found;
+}
+
+void
+show_module_taint()
+{
+	int i;
+	struct load_module *lm;
+	int maxnamelen = 0;
+	int maxtnts_len = 0;
+	char buf1[BUFSIZE];
+	char buf2[BUFSIZE];
+
+	if (!kernel_symbol_exists("tnts") &&
+		!MEMBER_EXISTS("tnt", "bit") &&
+		!MEMBER_EXISTS("tnt", "true") &&
+		!MEMBER_EXISTS("tnt", "false")) {
+			error(FATAL,
+				"tnts[] array does not exists in this kernel.\n");
+	}
+
+	for (i = 0; i < kt->mods_installed; i++) {
+		lm = &st->load_modules[i];
+		maxnamelen = strlen(lm->mod_name) > maxnamelen ?
+			strlen(lm->mod_name) : maxnamelen;
+	}
+
+	fprintf(fp, "%s  %s\n",
+		mkstring(buf1, maxnamelen, LJUST, "NAME"),
+		mkstring(buf2, 5, LJUST, "TAINT"));
+
+	for (i = 0; i < st->mods_installed; i++) {
+		lm = &st->load_modules[i];
+
+		if (is_module_taint(lm, buf2, &maxtnts_len)) {
+			fprintf(fp, "%s  ", mkstring(buf1, maxnamelen,
+				LJUST, lm->mod_name));
+			fprintf(fp, "%s\n", mkstring(buf2, maxtnts_len,
+				LJUST, buf2));
+		}
+	}
+}
 
 /*
  *  Do the simple list work for cmd_mod().
@@ -3655,6 +3773,10 @@ do_module_cmd(ulong flag, char *modref, ulong address,
 		reinit_modules();
         	do_module_cmd(LIST_MODULE_HDR, NULL, 0, NULL, NULL);
 		break;
+
+	case LIST_ALL_MODULE_TAINT:
+		show_module_taint();
+		break;
 	}
 }
 
