diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
index 5d26f3c6f918..4d1b7224bc38 100644
--- a/tools/bpf/resolve_btfids/main.c
+++ b/tools/bpf/resolve_btfids/main.c
@@ -35,6 +35,10 @@
  *             __BTF_ID__typedef__pid_t__1:
  *             .zero 4
  *
+ *   flags   - store specified flag values after ORing them into the data:
+ *	       __BTF_ID__flags__0x0_0x0_0x0_0x0_0x0__1:
+ *	       .zero 4
+ *
  *   set     - store symbol size into first 4 bytes and sort following
  *             ID list
  *
@@ -45,6 +49,21 @@
  *             .zero 4
  *             __BTF_ID__func__vfs_fallocate__4:
  *             .zero 4
+ *
+ *   set8    - store symbol size into first 4 bytes and sort following
+ *             ID list
+ *
+ *             __BTF_ID__set8__list:
+ *             .zero 8
+ *             list:
+ *             __BTF_ID__func__vfs_getattr__3:
+ *             .zero 4
+ *	       __BTF_ID__flags__0x0_0x0_0x0_0x0_0x0__4:
+ *             .zero 4
+ *             __BTF_ID__func__vfs_fallocate__5:
+ *             .zero 4
+ *	       __BTF_ID__flags__0x0_0x0_0x0_0x0_0x0__6:
+ *             .zero 4
  */
 
 #define  _GNU_SOURCE
@@ -57,6 +76,7 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <errno.h>
+#include <linux/list.h>
 #include <linux/rbtree.h>
 #include <linux/zalloc.h>
 #include <linux/err.h>
@@ -71,12 +91,17 @@
 #define BTF_UNION	"union"
 #define BTF_TYPEDEF	"typedef"
 #define BTF_FUNC	"func"
+#define BTF_FLAGS	"flags"
 #define BTF_SET		"set"
+#define BTF_SET8	"set8"
 
 #define ADDR_CNT	100
 
 struct btf_id {
-	struct rb_node	 rb_node;
+	union {
+		struct rb_node	 rb_node;
+		struct list_head ls_node;
+	};
 	char		*name;
 	union {
 		int	 id;
@@ -84,6 +109,8 @@ struct btf_id {
 	};
 	int		 addr_cnt;
 	bool		 is_set;
+	bool		 is_set8;
+	bool		 is_flag;
 	Elf64_Addr	 addr[ADDR_CNT];
 };
 
@@ -109,6 +136,8 @@ struct object {
 	struct rb_root	typedefs;
 	struct rb_root	funcs;
 
+	struct list_head flags;
+
 	int nr_funcs;
 	int nr_structs;
 	int nr_unions;
@@ -198,6 +227,20 @@ btf_id__add(struct rb_root *root, char *name, bool unique)
 	return id;
 }
 
+static struct btf_id *
+btf_id_flags__add(struct list_head *list, char *name)
+{
+	struct btf_id *id;
+
+	id = zalloc(sizeof(*id));
+	if (id) {
+		pr_debug("adding flags %s\n", name);
+		id->name = name;
+		list_add(&id->ls_node, list);
+	}
+	return id;
+}
+
 static char *get_id(const char *prefix_end)
 {
 	/*
@@ -231,14 +274,14 @@ static char *get_id(const char *prefix_end)
 	return id;
 }
 
-static struct btf_id *add_set(struct object *obj, char *name)
+static struct btf_id *add_set(struct object *obj, char *name, bool is_set8)
 {
 	/*
 	 * __BTF_ID__set__name
 	 * name =    ^
 	 * id   =         ^
 	 */
-	char *id = name + sizeof(BTF_SET "__") - 1;
+	char *id = name + (is_set8 ? sizeof(BTF_SET8 "__") : sizeof(BTF_SET "__")) - 1;
 	int len = strlen(name);
 
 	if (id >= name + len) {
@@ -262,6 +305,19 @@ static struct btf_id *add_symbol(struct rb_root *root, char *name, size_t size)
 	return btf_id__add(root, id, false);
 }
 
+static struct btf_id *add_flags(struct list_head *list, char *name, size_t size)
+{
+	char *id;
+
+	id = get_id(name + size);
+	if (!id) {
+		pr_err("FAILED to parse symbol name: %s\n", name);
+		return NULL;
+	}
+
+	return btf_id_flags__add(list, id);
+}
+
 /* Older libelf.h and glibc elf.h might not yet define the ELF compression types. */
 #ifndef SHF_COMPRESSED
 #define SHF_COMPRESSED (1 << 11) /* Section with compressed data. */
@@ -444,9 +500,26 @@ static int symbols_collect(struct object *obj)
 		} else if (!strncmp(prefix, BTF_FUNC, sizeof(BTF_FUNC) - 1)) {
 			obj->nr_funcs++;
 			id = add_symbol(&obj->funcs, prefix, sizeof(BTF_FUNC) - 1);
+		/* flags */
+		} else if (!strncmp(prefix, BTF_FLAGS, sizeof(BTF_FLAGS) - 1)) {
+			id = add_flags(&obj->flags, prefix, sizeof(BTF_FLAGS) - 1);
+			if (id)
+				id->is_flag = true;
+		/* set8 */
+		} else if (!strncmp(prefix, BTF_SET8, sizeof(BTF_SET8) - 1)) {
+			id = add_set(obj, prefix, true);
+			/*
+			 * SET8 objects store list's count, which is encoded
+			 * in symbol's size, together with 'cnt' field hence
+			 * that - 1.
+			 */
+			if (id) {
+				id->cnt = sym.st_size / sizeof(uint64_t) - 1;
+				id->is_set8 = true;
+			}
 		/* set */
 		} else if (!strncmp(prefix, BTF_SET, sizeof(BTF_SET) - 1)) {
-			id = add_set(obj, prefix);
+			id = add_set(obj, prefix, false);
 			/*
 			 * SET objects store list's count, which is encoded
 			 * in symbol's size, together with 'cnt' field hence
@@ -482,6 +555,7 @@ static int symbols_resolve(struct object *obj)
 	int nr_unions   = obj->nr_unions;
 	int nr_funcs    = obj->nr_funcs;
 	struct btf *base_btf = NULL;
+	struct btf_id *flags_id;
 	int err, type_id;
 	struct btf *btf;
 	__u32 nr_types;
@@ -558,6 +632,17 @@ static int symbols_resolve(struct object *obj)
 		}
 	}
 
+	/* Resolve all the BTF ID flags */
+	list_for_each_entry(flags_id, &obj->flags, ls_node) {
+		int f1, f2, f3, f4, f5;
+
+		if (sscanf(flags_id->name, "0x%x_0x%x_0x%x_0x%x_0x%x", &f1, &f2, &f3, &f4, &f5) != 5) {
+			pr_err("FAILED: malformed flags, can't resolve: %s\n", flags_id->name);
+			goto out;
+		}
+		flags_id->id = f1 | f2 | f3 | f4 | f5;
+	}
+
 	err = 0;
 out:
 	btf__free(base_btf);
@@ -571,7 +656,8 @@ static int id_patch(struct object *obj, struct btf_id *id)
 	int *ptr = data->d_buf;
 	int i;
 
-	if (!id->id && !id->is_set)
+	/* For set, set8, and flags, id->id may be 0 */
+	if (!id->id && !id->is_set && !id->is_set8 && !id->is_flag)
 		pr_err("WARN: resolve_btfids: unresolved symbol %s\n", id->name);
 
 	for (i = 0; i < id->addr_cnt; i++) {
@@ -611,6 +697,17 @@ static int __symbols_patch(struct object *obj, struct rb_root *root)
 	return 0;
 }
 
+static int flags_patch(struct object *obj)
+{
+	struct btf_id *flags_id;
+
+	list_for_each_entry(flags_id, &obj->flags, ls_node) {
+		if (id_patch(obj, flags_id))
+			return -1;
+	}
+	return 0;
+}
+
 static int cmp_id(const void *pa, const void *pb)
 {
 	const int *a = pa, *b = pb;
@@ -643,13 +740,13 @@ static int sets_patch(struct object *obj)
 		}
 
 		idx = idx / sizeof(int);
-		base = &ptr[idx] + 1;
+		base = &ptr[idx] + (id->is_set8 ? 2 : 1);
 		cnt = ptr[idx];
 
 		pr_debug("sorting  addr %5lu: cnt %6d [%s]\n",
 			 (idx + 1) * sizeof(int), cnt, id->name);
 
-		qsort(base, cnt, sizeof(int), cmp_id);
+		qsort(base, cnt, id->is_set8 ? sizeof(uint64_t) : sizeof(int), cmp_id);
 
 		next = rb_next(next);
 	}
@@ -667,6 +764,9 @@ static int symbols_patch(struct object *obj)
 	    __symbols_patch(obj, &obj->sets))
 		return -1;
 
+	if (flags_patch(obj))
+		return -1;
+
 	if (sets_patch(obj))
 		return -1;
 
@@ -715,6 +815,7 @@ int main(int argc, const char **argv)
 	};
 	int err = -1;
 
+	INIT_LIST_HEAD(&obj.flags);
 	argc = parse_options(argc, argv, btfid_options, resolve_btfids_usage,
 			     PARSE_OPT_STOP_AT_NON_OPTION);
 	if (argc != 1)
