struct key_type;
 struct key_owner;
+struct key_tag;
 struct keyring_list;
 struct keyring_name;
 
+struct key_tag {
+       struct rcu_head         rcu;
+       refcount_t              usage;
+       bool                    removed;        /* T when subject removed */
+};
+
 struct keyring_index_key {
        /* [!] If this structure is altered, the union in struct key must change too! */
        unsigned long           hash;                   /* Hash value */
                unsigned long x;
        };
        struct key_type         *type;
+       struct key_tag          *domain_tag;    /* Domain of operation */
        const char              *description;
 };
 
                        unsigned long   hash;
                        unsigned long   len_desc;
                        struct key_type *type;          /* type of key */
+                       struct key_tag  *domain_tag;    /* Domain of operation */
                        char            *description;
                };
        };
 extern void key_revoke(struct key *key);
 extern void key_invalidate(struct key *key);
 extern void key_put(struct key *key);
+extern bool key_put_tag(struct key_tag *tag);
 
 static inline struct key *__key_get(struct key *key)
 {
 
        type = (unsigned long)index_key->type;
        acc = mult_64x32_and_fold(type, desc_len + 13);
        acc = mult_64x32_and_fold(acc, 9207);
+       piece = (unsigned long)index_key->domain_tag;
+       acc = mult_64x32_and_fold(acc, piece);
+       acc = mult_64x32_and_fold(acc, 9207);
 
        for (;;) {
                n = desc_len;
 
 /*
  * Finalise an index key to include a part of the description actually in the
- * index key and to add in the hash too.
+ * index key, to set the domain tag and to calculate the hash.
  */
 void key_set_index_key(struct keyring_index_key *index_key)
 {
+       static struct key_tag default_domain_tag = { .usage = REFCOUNT_INIT(1), };
        size_t n = min_t(size_t, index_key->desc_len, sizeof(index_key->desc));
+
        memcpy(index_key->desc, index_key->description, n);
 
+       index_key->domain_tag = &default_domain_tag;
        hash_key_type_and_desc(index_key);
 }
 
+/**
+ * key_put_tag - Release a ref on a tag.
+ * @tag: The tag to release.
+ *
+ * This releases a reference the given tag and returns true if that ref was the
+ * last one.
+ */
+bool key_put_tag(struct key_tag *tag)
+{
+       if (refcount_dec_and_test(&tag->usage)) {
+               kfree_rcu(tag, rcu);
+               return true;
+       }
+
+       return false;
+}
+
 /*
  * Build the next index key chunk.
  *
                return index_key->x;
        case 2:
                return (unsigned long)index_key->type;
+       case 3:
+               return (unsigned long)index_key->domain_tag;
        default:
-               level -= 3;
+               level -= 4;
                if (desc_len <= sizeof(index_key->desc))
                        return 0;
 
        const struct key *key = keyring_ptr_to_key(object);
 
        return key->index_key.type == index_key->type &&
+               key->index_key.domain_tag == index_key->domain_tag &&
                key->index_key.desc_len == index_key->desc_len &&
                memcmp(key->index_key.description, index_key->description,
                       index_key->desc_len) == 0;
                goto differ;
        level += sizeof(unsigned long);
 
+       seg_a = (unsigned long)a->domain_tag;
+       seg_b = (unsigned long)b->domain_tag;
+       if ((seg_a ^ seg_b) != 0)
+               goto differ;
+       level += sizeof(unsigned long);
+
        i = sizeof(a->desc);
        if (a->desc_len <= i)
                goto same;