diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 0275a350dc23405862a39d687dfa14b1db3f9449..d5838249cda58fe511715035bd6cb5392b375710 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -2334,6 +2334,7 @@ static struct aa_sfs_entry aa_sfs_entry_versions[] = {
 	AA_SFS_FILE_BOOLEAN("v6",	1),
 	AA_SFS_FILE_BOOLEAN("v7",	1),
 	AA_SFS_FILE_BOOLEAN("v8",	1),
+	AA_SFS_FILE_BOOLEAN("v9",	1),
 	{ }
 };
 
diff --git a/security/apparmor/include/file.h b/security/apparmor/include/file.h
index 7517605a183d3dc5be09d5c0658b105b57129047..029cb20e322d5112a0cdde505f59b1c3393f3b58 100644
--- a/security/apparmor/include/file.h
+++ b/security/apparmor/include/file.h
@@ -142,6 +142,7 @@ static inline u16 dfa_map_xindex(u16 mask)
  */
 #define dfa_user_allow(dfa, state) (((ACCEPT_TABLE(dfa)[state]) & 0x7f) | \
 				    ((ACCEPT_TABLE(dfa)[state]) & 0x80000000))
+#define dfa_user_xbits(dfa, state) (((ACCEPT_TABLE(dfa)[state]) >> 7) & 0x7f)
 #define dfa_user_audit(dfa, state) ((ACCEPT_TABLE2(dfa)[state]) & 0x7f)
 #define dfa_user_quiet(dfa, state) (((ACCEPT_TABLE2(dfa)[state]) >> 7) & 0x7f)
 #define dfa_user_xindex(dfa, state) \
@@ -150,6 +151,8 @@ static inline u16 dfa_map_xindex(u16 mask)
 #define dfa_other_allow(dfa, state) ((((ACCEPT_TABLE(dfa)[state]) >> 14) & \
 				      0x7f) |				\
 				     ((ACCEPT_TABLE(dfa)[state]) & 0x80000000))
+#define dfa_other_xbits(dfa, state) \
+	((((ACCEPT_TABLE(dfa)[state]) >> 7) >> 14) & 0x7f)
 #define dfa_other_audit(dfa, state) (((ACCEPT_TABLE2(dfa)[state]) >> 14) & 0x7f)
 #define dfa_other_quiet(dfa, state) \
 	((((ACCEPT_TABLE2(dfa)[state]) >> 7) >> 14) & 0x7f)
diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
index 5eda003c0d45dbbf2ebcb38fe4c75677d7b28fa7..1c72a61108d3fa93ffa111cc30fe644d5e1e14f1 100644
--- a/security/apparmor/lib.c
+++ b/security/apparmor/lib.c
@@ -322,22 +322,39 @@ static u32 map_other(u32 x)
 		((x & 0x60) << 19);	/* SETOPT/GETOPT */
 }
 
+static u32 map_xbits(u32 x)
+{
+	return ((x & 0x1) << 7) |
+		((x & 0x7e) << 9);
+}
+
 void aa_compute_perms(struct aa_dfa *dfa, unsigned int state,
 		      struct aa_perms *perms)
 {
+	/* This mapping is convulated due to history.
+	 * v1-v4: only file perms
+	 * v5: added policydb which dropped in perm user conditional to
+	 *     gain new perm bits, but had to map around the xbits because
+	 *     the userspace compiler was still munging them.
+	 * v9: adds using the xbits in policydb because the compiler now
+	 *     supports treating policydb permission bits different.
+	 *     Unfortunately there is not way to force auditing on the
+	 *     perms represented by the xbits
+	 */
 	*perms = (struct aa_perms) {
-		.allow = dfa_user_allow(dfa, state),
+		.allow = dfa_user_allow(dfa, state) |
+			 map_xbits(dfa_user_xbits(dfa, state)),
 		.audit = dfa_user_audit(dfa, state),
-		.quiet = dfa_user_quiet(dfa, state),
+		.quiet = dfa_user_quiet(dfa, state) |
+			 map_xbits(dfa_other_xbits(dfa, state)),
 	};
 
-	/* for v5 perm mapping in the policydb, the other set is used
+	/* for v5-v9 perm mapping in the policydb, the other set is used
 	 * to extend the general perm set
 	 */
 	perms->allow |= map_other(dfa_other_allow(dfa, state));
 	perms->audit |= map_other(dfa_other_audit(dfa, state));
 	perms->quiet |= map_other(dfa_other_quiet(dfa, state));
-//	perms->xindex = dfa_user_xindex(dfa, state);
 }
 
 /**
diff --git a/security/apparmor/mount.c b/security/apparmor/mount.c
index fa64a2db3aec56ac3ebc39ba490ea5151ac5a83f..f6124724180333b363897e8715d866fa7058e52e 100644
--- a/security/apparmor/mount.c
+++ b/security/apparmor/mount.c
@@ -217,7 +217,6 @@ static struct aa_perms compute_mnt_perms(struct aa_dfa *dfa,
 		.allow = dfa_user_allow(dfa, state),
 		.audit = dfa_user_audit(dfa, state),
 		.quiet = dfa_user_quiet(dfa, state),
-		.xindex = dfa_user_xindex(dfa, state),
 	};
 
 	return perms;