struct svm_range *prange;
        uint32_t prefetch_loc = KFD_IOCTL_SVM_LOCATION_UNDEFINED;
        uint32_t location = KFD_IOCTL_SVM_LOCATION_UNDEFINED;
-       uint32_t flags = 0xffffffff;
+       uint32_t flags_and = 0xffffffff;
+       uint32_t flags_or = 0;
        int gpuidx;
        uint32_t i;
 
                        get_accessible = true;
                        break;
                case KFD_IOCTL_SVM_ATTR_SET_FLAGS:
+               case KFD_IOCTL_SVM_ATTR_CLR_FLAGS:
                        get_flags = true;
                        break;
                case KFD_IOCTL_SVM_ATTR_GRANULARITY:
                        get_granularity = true;
                        break;
-               case KFD_IOCTL_SVM_ATTR_CLR_FLAGS:
                case KFD_IOCTL_SVM_ATTR_ACCESS_IN_PLACE:
                case KFD_IOCTL_SVM_ATTR_NO_ACCESS:
                        fallthrough;
        if (!node) {
                pr_debug("range attrs not found return default values\n");
                svm_range_set_default_attributes(&location, &prefetch_loc,
-                                                &granularity, &flags);
+                                                &granularity, &flags_and);
+               flags_or = flags_and;
                if (p->xnack_enabled)
                        bitmap_copy(bitmap_access, svms->bitmap_supported,
                                    MAX_GPU_INSTANCE);
                        bitmap_and(bitmap_aip, bitmap_aip,
                                   prange->bitmap_aip, MAX_GPU_INSTANCE);
                }
-               if (get_flags)
-                       flags &= prange->flags;
+               if (get_flags) {
+                       flags_and &= prange->flags;
+                       flags_or |= prange->flags;
+               }
 
                if (get_granularity && prange->granularity < granularity)
                        granularity = prange->granularity;
                                attrs[i].type = KFD_IOCTL_SVM_ATTR_NO_ACCESS;
                        break;
                case KFD_IOCTL_SVM_ATTR_SET_FLAGS:
-                       attrs[i].value = flags;
+                       attrs[i].value = flags_and;
+                       break;
+               case KFD_IOCTL_SVM_ATTR_CLR_FLAGS:
+                       attrs[i].value = ~flags_or;
                        break;
                case KFD_IOCTL_SVM_ATTR_GRANULARITY:
                        attrs[i].value = (uint32_t)granularity;
 
  * - 1.3 - Add SMI events support
  * - 1.4 - Indicate new SRAM EDC bit in device properties
  * - 1.5 - Add SVM API
+ * - 1.6 - Query clear flags in SVM get_attr API
  */
 #define KFD_IOCTL_MAJOR_VERSION 1
-#define KFD_IOCTL_MINOR_VERSION 5
+#define KFD_IOCTL_MINOR_VERSION 6
 
 struct kfd_ioctl_get_version_args {
        __u32 major_version;    /* from KFD */
  * @KFD_IOCTL_SVM_ATTR_PREFERRED_LOC or
  * @KFD_IOCTL_SVM_ATTR_PREFETCH_LOC resepctively. For
  * @KFD_IOCTL_SVM_ATTR_SET_FLAGS, flags of all pages will be
- * aggregated by bitwise AND. The minimum  migration granularity
- * throughout the range will be returned for
- * @KFD_IOCTL_SVM_ATTR_GRANULARITY.
+ * aggregated by bitwise AND. That means, a flag will be set in the
+ * output, if that flag is set for all pages in the range. For
+ * @KFD_IOCTL_SVM_ATTR_CLR_FLAGS, flags of all pages will be
+ * aggregated by bitwise NOR. That means, a flag will be set in the
+ * output, if that flag is clear for all pages in the range.
+ * The minimum migration granularity throughout the range will be
+ * returned for @KFD_IOCTL_SVM_ATTR_GRANULARITY.
  *
  * Querying of accessibility attributes works by initializing the
  * attribute type to @KFD_IOCTL_SVM_ATTR_ACCESS and the value to the
  * GPUID being queried. Multiple attributes can be given to allow
  * querying multiple GPUIDs. The ioctl function overwrites the
  * attribute type to indicate the access for the specified GPU.
- *
- * @KFD_IOCTL_SVM_ATTR_CLR_FLAGS is invalid for
- * @KFD_IOCTL_SVM_OP_GET_ATTR.
  */
 struct kfd_ioctl_svm_args {
        __u64 start_addr;