unsigned int n_placements;
        unsigned int placement_mask;
        unsigned long flags;
+       unsigned int pat_index;
 };
 
 static void repr_placements(char *buf, size_t size,
        return 0;
 }
 
+static int ext_set_pat(struct i915_user_extension __user *base, void *data)
+{
+       struct create_ext *ext_data = data;
+       struct drm_i915_private *i915 = ext_data->i915;
+       struct drm_i915_gem_create_ext_set_pat ext;
+       unsigned int max_pat_index;
+
+       BUILD_BUG_ON(sizeof(struct drm_i915_gem_create_ext_set_pat) !=
+                    offsetofend(struct drm_i915_gem_create_ext_set_pat, rsvd));
+
+       /* Limiting the extension only to Meteor Lake */
+       if (!IS_METEORLAKE(i915))
+               return -ENODEV;
+
+       if (copy_from_user(&ext, base, sizeof(ext)))
+               return -EFAULT;
+
+       max_pat_index = INTEL_INFO(i915)->max_pat_index;
+
+       if (ext.pat_index > max_pat_index) {
+               drm_dbg(&i915->drm, "PAT index is invalid: %u\n",
+                       ext.pat_index);
+               return -EINVAL;
+       }
+
+       ext_data->pat_index = ext.pat_index;
+
+       return 0;
+}
+
 static const i915_user_extension_fn create_extensions[] = {
        [I915_GEM_CREATE_EXT_MEMORY_REGIONS] = ext_set_placements,
        [I915_GEM_CREATE_EXT_PROTECTED_CONTENT] = ext_set_protected,
+       [I915_GEM_CREATE_EXT_SET_PAT] = ext_set_pat,
 };
 
+#define PAT_INDEX_NOT_SET      0xffff
 /**
  * i915_gem_create_ext_ioctl - Creates a new mm object and returns a handle to it.
  * @dev: drm device pointer
        if (args->flags & ~I915_GEM_CREATE_EXT_FLAG_NEEDS_CPU_ACCESS)
                return -EINVAL;
 
+       ext_data.pat_index = PAT_INDEX_NOT_SET;
        ret = i915_user_extensions(u64_to_user_ptr(args->extensions),
                                   create_extensions,
                                   ARRAY_SIZE(create_extensions),
        if (IS_ERR(obj))
                return PTR_ERR(obj);
 
+       if (ext_data.pat_index != PAT_INDEX_NOT_SET) {
+               i915_gem_object_set_pat_index(obj, ext_data.pat_index);
+               /* Mark pat_index is set by UMD */
+               obj->pat_set_by_user = true;
+       }
+
        return i915_gem_publish(obj, file, &args->size, &args->handle);
 }
 
         *
         * For I915_GEM_CREATE_EXT_PROTECTED_CONTENT usage see
         * struct drm_i915_gem_create_ext_protected_content.
+        *
+        * For I915_GEM_CREATE_EXT_SET_PAT usage see
+        * struct drm_i915_gem_create_ext_set_pat.
         */
 #define I915_GEM_CREATE_EXT_MEMORY_REGIONS 0
 #define I915_GEM_CREATE_EXT_PROTECTED_CONTENT 1
+#define I915_GEM_CREATE_EXT_SET_PAT 2
        __u64 extensions;
 };
 
        __u32 flags;
 };
 
+/**
+ * struct drm_i915_gem_create_ext_set_pat - The
+ * I915_GEM_CREATE_EXT_SET_PAT extension.
+ *
+ * If this extension is provided, the specified caching policy (PAT index) is
+ * applied to the buffer object.
+ *
+ * Below is an example on how to create an object with specific caching policy:
+ *
+ * .. code-block:: C
+ *
+ *      struct drm_i915_gem_create_ext_set_pat set_pat_ext = {
+ *              .base = { .name = I915_GEM_CREATE_EXT_SET_PAT },
+ *              .pat_index = 0,
+ *      };
+ *      struct drm_i915_gem_create_ext create_ext = {
+ *              .size = PAGE_SIZE,
+ *              .extensions = (uintptr_t)&set_pat_ext,
+ *      };
+ *
+ *      int err = ioctl(fd, DRM_IOCTL_I915_GEM_CREATE_EXT, &create_ext);
+ *      if (err) ...
+ */
+struct drm_i915_gem_create_ext_set_pat {
+       /** @base: Extension link. See struct i915_user_extension. */
+       struct i915_user_extension base;
+       /**
+        * @pat_index: PAT index to be set
+        * PAT index is a bit field in Page Table Entry to control caching
+        * behaviors for GPU accesses. The definition of PAT index is
+        * platform dependent and can be found in hardware specifications,
+        */
+       __u32 pat_index;
+       /** @rsvd: reserved for future use */
+       __u32 rsvd;
+};
+
 /* ID of the protected content session managed by i915 when PXP is active */
 #define I915_PROTECTED_CONTENT_DEFAULT_SESSION 0xf