return 0;
 }
 
-static int bpf_object__validate(struct bpf_object *obj)
+static bool bpf_prog_type__needs_kver(enum bpf_prog_type type)
+{
+       switch (type) {
+       case BPF_PROG_TYPE_SOCKET_FILTER:
+       case BPF_PROG_TYPE_SCHED_CLS:
+       case BPF_PROG_TYPE_SCHED_ACT:
+       case BPF_PROG_TYPE_XDP:
+       case BPF_PROG_TYPE_CGROUP_SKB:
+       case BPF_PROG_TYPE_CGROUP_SOCK:
+       case BPF_PROG_TYPE_LWT_IN:
+       case BPF_PROG_TYPE_LWT_OUT:
+       case BPF_PROG_TYPE_LWT_XMIT:
+       case BPF_PROG_TYPE_SOCK_OPS:
+       case BPF_PROG_TYPE_SK_SKB:
+       case BPF_PROG_TYPE_CGROUP_DEVICE:
+       case BPF_PROG_TYPE_SK_MSG:
+       case BPF_PROG_TYPE_CGROUP_SOCK_ADDR:
+               return false;
+       case BPF_PROG_TYPE_UNSPEC:
+       case BPF_PROG_TYPE_KPROBE:
+       case BPF_PROG_TYPE_TRACEPOINT:
+       case BPF_PROG_TYPE_PERF_EVENT:
+       case BPF_PROG_TYPE_RAW_TRACEPOINT:
+       default:
+               return true;
+       }
+}
+
+static int bpf_object__validate(struct bpf_object *obj, bool needs_kver)
 {
-       if (obj->kern_version == 0) {
+       if (needs_kver && obj->kern_version == 0) {
                pr_warning("%s doesn't provide kernel version\n",
                           obj->path);
                return -LIBBPF_ERRNO__KVERSION;
 }
 
 static struct bpf_object *
-__bpf_object__open(const char *path, void *obj_buf, size_t obj_buf_sz)
+__bpf_object__open(const char *path, void *obj_buf, size_t obj_buf_sz,
+                  bool needs_kver)
 {
        struct bpf_object *obj;
        int err;
        CHECK_ERR(bpf_object__check_endianness(obj), err, out);
        CHECK_ERR(bpf_object__elf_collect(obj), err, out);
        CHECK_ERR(bpf_object__collect_reloc(obj), err, out);
-       CHECK_ERR(bpf_object__validate(obj), err, out);
+       CHECK_ERR(bpf_object__validate(obj, needs_kver), err, out);
 
        bpf_object__elf_finish(obj);
        return obj;
 
        pr_debug("loading %s\n", path);
 
-       return __bpf_object__open(path, NULL, 0);
+       return __bpf_object__open(path, NULL, 0, true);
 }
 
 struct bpf_object *bpf_object__open_buffer(void *obj_buf,
        pr_debug("loading object '%s' from buffer\n",
                 name);
 
-       return __bpf_object__open(name, obj_buf, obj_buf_sz);
+       return __bpf_object__open(name, obj_buf, obj_buf_sz, true);
 }
 
 int bpf_object__unload(struct bpf_object *obj)
 
        if (!attr)
                return -EINVAL;
+       if (!attr->file)
+               return -EINVAL;
 
-       obj = bpf_object__open(attr->file);
+       obj = __bpf_object__open(attr->file, NULL, 0,
+                                bpf_prog_type__needs_kver(attr->prog_type));
        if (IS_ERR(obj))
                return -ENOENT;