* [PATCH v3] drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise
[not found] <20260129000147.339361-1-jia.yao@intel.com>
@ 2026-01-30 22:07 ` Jia Yao
2026-02-03 2:54 ` Lin, Shuicheng
2026-02-04 15:13 ` Souza, Jose
2026-02-03 15:48 ` [PATCH v4] " Jia Yao
` (3 subsequent siblings)
4 siblings, 2 replies; 20+ messages in thread
From: Jia Yao @ 2026-01-30 22:07 UTC (permalink / raw)
To: intel-xe
Cc: Jia Yao, stable, Mathew Alwin, Michal Mrozek, Matthew Brost,
Matthew Auld
Add validation in xe_vm_madvise_ioctl() to reject PAT indices with
XE_COH_NONE coherency mode when applied to CPU cached memory.
Using coh_none with CPU cached buffers is a security issue. When the
kernel clears pages before reallocation, the clear operation stays in
CPU cache (dirty). GPU with coh_none can bypass CPU caches and read
stale sensitive data directly from DRAM, potentially leaking data from
previously freed pages of other processes.
This aligns with the existing validation in vm_bind path
(xe_vm_bind_ioctl_validate_bo).
v2(Matthew brost)
- Add fixes
- Move one debug print to better place
v3(Matthew Auld)
- Should be drm/xe/uapi
- More Cc
Fixes: ada7486c5668 ("drm/xe: Implement madvise ioctl for xe")
Cc: stable@vger.kernel.org # v6.18
Cc: Mathew Alwin <alwin.mathew@intel.com>
Cc: Michal Mrozek <michal.mrozek@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Jia Yao <jia.yao@intel.com>
---
drivers/gpu/drm/xe/xe_vm_madvise.c | 47 ++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/drivers/gpu/drm/xe/xe_vm_madvise.c b/drivers/gpu/drm/xe/xe_vm_madvise.c
index add9a6ca2390..50b82e821da7 100644
--- a/drivers/gpu/drm/xe/xe_vm_madvise.c
+++ b/drivers/gpu/drm/xe/xe_vm_madvise.c
@@ -352,6 +352,44 @@ static void xe_madvise_details_fini(struct xe_madvise_details *details)
drm_pagemap_put(details->dpagemap);
}
+static bool check_pat_args_are_sane(struct xe_device *xe,
+ struct xe_vmas_in_madvise_range *madvise_range,
+ u16 pat_index)
+{
+ u16 coh_mode = xe_pat_index_get_coh_mode(xe, pat_index);
+ int i;
+
+ /*
+ * Using coh_none with CPU cached buffers is not allowed.
+ * Otherwise CPU page clearing can be bypassed, which is a
+ * security issue. GPU can directly access system memory and
+ * bypass CPU caches, potentially reading stale sensitive data
+ * from previously freed pages.
+ */
+ if (coh_mode != XE_COH_NONE)
+ return true;
+
+ for (i = 0; i < madvise_range->num_vmas; i++) {
+ struct xe_vma *vma = madvise_range->vmas[i];
+ struct xe_bo *bo = xe_vma_bo(vma);
+
+ if (bo) {
+ /* BO with WB caching + COH_NONE is not allowed */
+ if (XE_IOCTL_DBG(xe, bo->cpu_caching == DRM_XE_GEM_CPU_CACHING_WB))
+ return false;
+ /* Imported dma-buf without caching info, assume cached */
+ if (XE_IOCTL_DBG(xe, !bo->cpu_caching))
+ return false;
+ } else if (XE_IOCTL_DBG(xe, xe_vma_is_cpu_addr_mirror(vma)) ||
+ xe_vma_is_userptr(vma)) {
+ /* System memory (userptr/SVM) is always CPU cached */
+ return false;
+ }
+ }
+
+ return true;
+}
+
static bool check_bo_args_are_sane(struct xe_vm *vm, struct xe_vma **vmas,
int num_vmas, u32 atomic_val)
{
@@ -442,6 +480,14 @@ int xe_vm_madvise_ioctl(struct drm_device *dev, void *data, struct drm_file *fil
if (err || !madvise_range.num_vmas)
goto madv_fini;
+ if (args->type == DRM_XE_MEM_RANGE_ATTR_PAT) {
+ if (!check_pat_args_are_sane(xe, &madvise_range,
+ args->pat_index.val)) {
+ err = -EINVAL;
+ goto free_vmas;
+ }
+ }
+
if (madvise_range.has_bo_vmas) {
if (args->type == DRM_XE_MEM_RANGE_ATTR_ATOMIC) {
if (!check_bo_args_are_sane(vm, madvise_range.vmas,
@@ -485,6 +531,7 @@ int xe_vm_madvise_ioctl(struct drm_device *dev, void *data, struct drm_file *fil
err_fini:
if (madvise_range.has_bo_vmas)
drm_exec_fini(&exec);
+free_vmas:
kfree(madvise_range.vmas);
madvise_range.vmas = NULL;
madv_fini:
--
2.43.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* RE: [PATCH v3] drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise
2026-01-30 22:07 ` [PATCH v3] drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise Jia Yao
@ 2026-02-03 2:54 ` Lin, Shuicheng
2026-02-04 15:13 ` Souza, Jose
1 sibling, 0 replies; 20+ messages in thread
From: Lin, Shuicheng @ 2026-02-03 2:54 UTC (permalink / raw)
To: Yao, Jia, intel-xe@lists.freedesktop.org
Cc: Yao, Jia, stable@vger.kernel.org, Mathew, Alwin, Mrozek, Michal,
Brost, Matthew, Auld, Matthew
Some comments not for this patch but for related code in this file.
On Fri, Jan 30, 2026 2:08 PM Jia Yao wrote:
> Add validation in xe_vm_madvise_ioctl() to reject PAT indices with
> XE_COH_NONE coherency mode when applied to CPU cached memory.
>
> Using coh_none with CPU cached buffers is a security issue. When the kernel
> clears pages before reallocation, the clear operation stays in CPU cache (dirty).
> GPU with coh_none can bypass CPU caches and read stale sensitive data directly
> from DRAM, potentially leaking data from previously freed pages of other
> processes.
>
> This aligns with the existing validation in vm_bind path
> (xe_vm_bind_ioctl_validate_bo).
>
> v2(Matthew brost)
> - Add fixes
> - Move one debug print to better place
>
> v3(Matthew Auld)
> - Should be drm/xe/uapi
> - More Cc
>
> Fixes: ada7486c5668 ("drm/xe: Implement madvise ioctl for xe")
> Cc: stable@vger.kernel.org # v6.18
> Cc: Mathew Alwin <alwin.mathew@intel.com>
> Cc: Michal Mrozek <michal.mrozek@intel.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
> Cc: Matthew Auld <matthew.auld@intel.com>
> Signed-off-by: Jia Yao <jia.yao@intel.com>
> ---
> drivers/gpu/drm/xe/xe_vm_madvise.c | 47
> ++++++++++++++++++++++++++++++
> 1 file changed, 47 insertions(+)
>
> diff --git a/drivers/gpu/drm/xe/xe_vm_madvise.c
> b/drivers/gpu/drm/xe/xe_vm_madvise.c
> index add9a6ca2390..50b82e821da7 100644
> --- a/drivers/gpu/drm/xe/xe_vm_madvise.c
> +++ b/drivers/gpu/drm/xe/xe_vm_madvise.c
> @@ -352,6 +352,44 @@ static void xe_madvise_details_fini(struct
> xe_madvise_details *details)
> drm_pagemap_put(details->dpagemap);
> }
>
> +static bool check_pat_args_are_sane(struct xe_device *xe,
> + struct xe_vmas_in_madvise_range
> *madvise_range,
> + u16 pat_index)
> +{
> + u16 coh_mode = xe_pat_index_get_coh_mode(xe, pat_index);
> + int i;
> +
> + /*
> + * Using coh_none with CPU cached buffers is not allowed.
> + * Otherwise CPU page clearing can be bypassed, which is a
> + * security issue. GPU can directly access system memory and
> + * bypass CPU caches, potentially reading stale sensitive data
> + * from previously freed pages.
> + */
> + if (coh_mode != XE_COH_NONE)
> + return true;
> +
> + for (i = 0; i < madvise_range->num_vmas; i++) {
> + struct xe_vma *vma = madvise_range->vmas[i];
> + struct xe_bo *bo = xe_vma_bo(vma);
> +
> + if (bo) {
> + /* BO with WB caching + COH_NONE is not allowed */
> + if (XE_IOCTL_DBG(xe, bo->cpu_caching ==
> DRM_XE_GEM_CPU_CACHING_WB))
> + return false;
> + /* Imported dma-buf without caching info, assume
> cached */
> + if (XE_IOCTL_DBG(xe, !bo->cpu_caching))
> + return false;
> + } else if (XE_IOCTL_DBG(xe, xe_vma_is_cpu_addr_mirror(vma))
> ||
> + xe_vma_is_userptr(vma)) {
> + /* System memory (userptr/SVM) is always CPU cached
> */
> + return false;
> + }
> + }
> +
> + return true;
> +}
> +
> static bool check_bo_args_are_sane(struct xe_vm *vm, struct xe_vma **vmas,
> int num_vmas, u32 atomic_val)
> {
> @@ -442,6 +480,14 @@ int xe_vm_madvise_ioctl(struct drm_device *dev, void
> *data, struct drm_file *fil
> if (err || !madvise_range.num_vmas)
> goto madv_fini;
>
> + if (args->type == DRM_XE_MEM_RANGE_ATTR_PAT) {
> + if (!check_pat_args_are_sane(xe, &madvise_range,
> + args->pat_index.val)) {
> + err = -EINVAL;
> + goto free_vmas;
> + }
> + }
> +
> if (madvise_range.has_bo_vmas) {
> if (args->type == DRM_XE_MEM_RANGE_ATTR_ATOMIC) {
> if (!check_bo_args_are_sane(vm, madvise_range.vmas,
While go through the code, I find it is "goto madv_fini;" here, which should be corrected to "goto free_vmas" also.
Could you please use another patch to fix it? Thanks.
> @@ -485,6 +531,7 @@ int xe_vm_madvise_ioctl(struct drm_device *dev, void
> *data, struct drm_file *fil
> err_fini:
> if (madvise_range.has_bo_vmas)
> drm_exec_fini(&exec);
> +free_vmas:
> kfree(madvise_range.vmas);
> madvise_range.vmas = NULL;
This line could be removed; there is no need to set NULL for a local parameter here.
Shuicheng
> madv_fini:
> --
> 2.43.0
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v4] drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise
[not found] <20260129000147.339361-1-jia.yao@intel.com>
2026-01-30 22:07 ` [PATCH v3] drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise Jia Yao
@ 2026-02-03 15:48 ` Jia Yao
2026-02-03 16:38 ` Matthew Auld
2026-03-10 14:50 ` Mrozek, Michal
2026-03-16 7:22 ` [PATCH v5 0/2] drm/xe: PAT index validation for CPU_ADDR_MIRROR and Jia Yao
` (2 subsequent siblings)
4 siblings, 2 replies; 20+ messages in thread
From: Jia Yao @ 2026-02-03 15:48 UTC (permalink / raw)
To: intel-xe
Cc: Jia Yao, stable, Shuicheng Lin, Mathew Alwin, Michal Mrozek,
Matthew Brost, Matthew Auld
Add validation in xe_vm_madvise_ioctl() to reject PAT indices with
XE_COH_NONE coherency mode when applied to CPU cached memory.
Using coh_none with CPU cached buffers is a security issue. When the
kernel clears pages before reallocation, the clear operation stays in
CPU cache (dirty). GPU with coh_none can bypass CPU caches and read
stale sensitive data directly from DRAM, potentially leaking data from
previously freed pages of other processes.
This aligns with the existing validation in vm_bind path
(xe_vm_bind_ioctl_validate_bo).
v2(Matthew brost)
- Add fixes
- Move one debug print to better place
v3(Matthew Auld)
- Should be drm/xe/uapi
- More Cc
v4(Shuicheng Lin)
- Fix kmem leak issues by the way
Fixes: ada7486c5668 ("drm/xe: Implement madvise ioctl for xe")
Cc: stable@vger.kernel.org # v6.18
Cc: Shuicheng Lin <shuicheng.lin@intel.com>
Cc: Mathew Alwin <alwin.mathew@intel.com>
Cc: Michal Mrozek <michal.mrozek@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Jia Yao <jia.yao@intel.com>
---
drivers/gpu/drm/xe/xe_vm_madvise.c | 55 +++++++++++++++++++++++++++---
1 file changed, 50 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_vm_madvise.c b/drivers/gpu/drm/xe/xe_vm_madvise.c
index add9a6ca2390..bf41fe75a336 100644
--- a/drivers/gpu/drm/xe/xe_vm_madvise.c
+++ b/drivers/gpu/drm/xe/xe_vm_madvise.c
@@ -74,7 +74,7 @@ static int get_vmas(struct xe_vm *vm, struct xe_vmas_in_madvise_range *madvise_r
}
madvise_range->vmas[madvise_range->num_vmas] = vma;
- (madvise_range->num_vmas)++;
+ madvise_range->num_vmas++;
}
if (!madvise_range->num_vmas)
@@ -352,6 +352,43 @@ static void xe_madvise_details_fini(struct xe_madvise_details *details)
drm_pagemap_put(details->dpagemap);
}
+static bool check_pat_args_are_sane(struct xe_device *xe,
+ struct xe_vmas_in_madvise_range *madvise_range,
+ u16 pat_index)
+{
+ u16 coh_mode = xe_pat_index_get_coh_mode(xe, pat_index);
+ int i;
+
+ /*
+ * Using coh_none with CPU cached buffers is not allowed.
+ * Otherwise CPU page clearing can be bypassed, which is a
+ * security issue. GPU can directly access system memory and
+ * bypass CPU caches, potentially reading stale sensitive data
+ * from previously freed pages.
+ */
+ if (coh_mode != XE_COH_NONE)
+ return true;
+
+ for (i = 0; i < madvise_range->num_vmas; i++) {
+ struct xe_vma *vma = madvise_range->vmas[i];
+ struct xe_bo *bo = xe_vma_bo(vma);
+
+ if (bo) {
+ /* BO with WB caching + COH_NONE is not allowed */
+ if (XE_IOCTL_DBG(xe, bo->cpu_caching == DRM_XE_GEM_CPU_CACHING_WB))
+ return false;
+ /* Imported dma-buf without caching info, assume cached */
+ if (XE_IOCTL_DBG(xe, !bo->cpu_caching))
+ return false;
+ } else if (XE_IOCTL_DBG(xe, xe_vma_is_cpu_addr_mirror(vma) ||
+ xe_vma_is_userptr(vma)))
+ /* System memory (userptr/SVM) is always CPU cached */
+ return false;
+ }
+
+ return true;
+}
+
static bool check_bo_args_are_sane(struct xe_vm *vm, struct xe_vma **vmas,
int num_vmas, u32 atomic_val)
{
@@ -388,12 +425,12 @@ static bool check_bo_args_are_sane(struct xe_vm *vm, struct xe_vma **vmas,
return true;
}
/**
- * xe_vm_madvise_ioctl - Handle MADVise ioctl for a VM
+ * xe_vm_madvise_ioctl - Handle madvise ioctl for a VM
* @dev: DRM device pointer
* @data: Pointer to ioctl data (drm_xe_madvise*)
* @file: DRM file pointer
*
- * Handles the MADVISE ioctl to provide memory advice for vma's within
+ * Handles the madvise ioctl to provide memory advice for vma's within
* input range.
*
* Return: 0 on success or a negative error code on failure.
@@ -442,13 +479,21 @@ int xe_vm_madvise_ioctl(struct drm_device *dev, void *data, struct drm_file *fil
if (err || !madvise_range.num_vmas)
goto madv_fini;
+ if (args->type == DRM_XE_MEM_RANGE_ATTR_PAT) {
+ if (!check_pat_args_are_sane(xe, &madvise_range,
+ args->pat_index.val)) {
+ err = -EINVAL;
+ goto free_vmas;
+ }
+ }
+
if (madvise_range.has_bo_vmas) {
if (args->type == DRM_XE_MEM_RANGE_ATTR_ATOMIC) {
if (!check_bo_args_are_sane(vm, madvise_range.vmas,
madvise_range.num_vmas,
args->atomic.val)) {
err = -EINVAL;
- goto madv_fini;
+ goto free_vmas;
}
}
@@ -485,8 +530,8 @@ int xe_vm_madvise_ioctl(struct drm_device *dev, void *data, struct drm_file *fil
err_fini:
if (madvise_range.has_bo_vmas)
drm_exec_fini(&exec);
+free_vmas:
kfree(madvise_range.vmas);
- madvise_range.vmas = NULL;
madv_fini:
xe_madvise_details_fini(&details);
unlock_vm:
--
2.43.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v4] drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise
2026-02-03 15:48 ` [PATCH v4] " Jia Yao
@ 2026-02-03 16:38 ` Matthew Auld
2026-02-03 16:59 ` Yao, Jia
2026-03-10 14:50 ` Mrozek, Michal
1 sibling, 1 reply; 20+ messages in thread
From: Matthew Auld @ 2026-02-03 16:38 UTC (permalink / raw)
To: Jia Yao, intel-xe
Cc: stable, Shuicheng Lin, Mathew Alwin, Michal Mrozek, Matthew Brost
On 03/02/2026 15:48, Jia Yao wrote:
> Add validation in xe_vm_madvise_ioctl() to reject PAT indices with
> XE_COH_NONE coherency mode when applied to CPU cached memory.
>
> Using coh_none with CPU cached buffers is a security issue. When the
> kernel clears pages before reallocation, the clear operation stays in
> CPU cache (dirty). GPU with coh_none can bypass CPU caches and read
> stale sensitive data directly from DRAM, potentially leaking data from
> previously freed pages of other processes.
>
> This aligns with the existing validation in vm_bind path
> (xe_vm_bind_ioctl_validate_bo).
>
> v2(Matthew brost)
> - Add fixes
> - Move one debug print to better place
>
> v3(Matthew Auld)
> - Should be drm/xe/uapi
> - More Cc
>
> v4(Shuicheng Lin)
> - Fix kmem leak issues by the way
>
> Fixes: ada7486c5668 ("drm/xe: Implement madvise ioctl for xe")
> Cc: stable@vger.kernel.org # v6.18
> Cc: Shuicheng Lin <shuicheng.lin@intel.com>
> Cc: Mathew Alwin <alwin.mathew@intel.com>
> Cc: Michal Mrozek <michal.mrozek@intel.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
> Cc: Matthew Auld <matthew.auld@intel.com>
> Signed-off-by: Jia Yao <jia.yao@intel.com>
Unless I'm blind, it looks like there is some missing validation on the
pat_index coming from userspace also, where we can trigger OOB kernel
read when calling get_coh_mode(), if malicious user gives you a bogus
too large index. I think we need to fix that also, maybe as a seperate
patch in this series or just send as seperate fix and get it landed ASAP?
> ---
> drivers/gpu/drm/xe/xe_vm_madvise.c | 55 +++++++++++++++++++++++++++---
> 1 file changed, 50 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_vm_madvise.c b/drivers/gpu/drm/xe/xe_vm_madvise.c
> index add9a6ca2390..bf41fe75a336 100644
> --- a/drivers/gpu/drm/xe/xe_vm_madvise.c
> +++ b/drivers/gpu/drm/xe/xe_vm_madvise.c
> @@ -74,7 +74,7 @@ static int get_vmas(struct xe_vm *vm, struct xe_vmas_in_madvise_range *madvise_r
> }
>
> madvise_range->vmas[madvise_range->num_vmas] = vma;
> - (madvise_range->num_vmas)++;
> + madvise_range->num_vmas++;
> }
>
> if (!madvise_range->num_vmas)
> @@ -352,6 +352,43 @@ static void xe_madvise_details_fini(struct xe_madvise_details *details)
> drm_pagemap_put(details->dpagemap);
> }
>
> +static bool check_pat_args_are_sane(struct xe_device *xe,
> + struct xe_vmas_in_madvise_range *madvise_range,
> + u16 pat_index)
> +{
> + u16 coh_mode = xe_pat_index_get_coh_mode(xe, pat_index);
> + int i;
> +
> + /*
> + * Using coh_none with CPU cached buffers is not allowed.
> + * Otherwise CPU page clearing can be bypassed, which is a
> + * security issue. GPU can directly access system memory and
> + * bypass CPU caches, potentially reading stale sensitive data
> + * from previously freed pages.
> + */
> + if (coh_mode != XE_COH_NONE)
> + return true;
> +
> + for (i = 0; i < madvise_range->num_vmas; i++) {
> + struct xe_vma *vma = madvise_range->vmas[i];
> + struct xe_bo *bo = xe_vma_bo(vma);
> +
> + if (bo) {
> + /* BO with WB caching + COH_NONE is not allowed */
> + if (XE_IOCTL_DBG(xe, bo->cpu_caching == DRM_XE_GEM_CPU_CACHING_WB))
> + return false;
> + /* Imported dma-buf without caching info, assume cached */
> + if (XE_IOCTL_DBG(xe, !bo->cpu_caching))
> + return false;
> + } else if (XE_IOCTL_DBG(xe, xe_vma_is_cpu_addr_mirror(vma) ||
> + xe_vma_is_userptr(vma)))
> + /* System memory (userptr/SVM) is always CPU cached */
> + return false;
> + }
> +
> + return true;
> +}
> +
> static bool check_bo_args_are_sane(struct xe_vm *vm, struct xe_vma **vmas,
> int num_vmas, u32 atomic_val)
> {
> @@ -388,12 +425,12 @@ static bool check_bo_args_are_sane(struct xe_vm *vm, struct xe_vma **vmas,
> return true;
> }
> /**
> - * xe_vm_madvise_ioctl - Handle MADVise ioctl for a VM
> + * xe_vm_madvise_ioctl - Handle madvise ioctl for a VM
> * @dev: DRM device pointer
> * @data: Pointer to ioctl data (drm_xe_madvise*)
> * @file: DRM file pointer
> *
> - * Handles the MADVISE ioctl to provide memory advice for vma's within
> + * Handles the madvise ioctl to provide memory advice for vma's within
> * input range.
> *
> * Return: 0 on success or a negative error code on failure.
> @@ -442,13 +479,21 @@ int xe_vm_madvise_ioctl(struct drm_device *dev, void *data, struct drm_file *fil
> if (err || !madvise_range.num_vmas)
> goto madv_fini;
>
> + if (args->type == DRM_XE_MEM_RANGE_ATTR_PAT) {
> + if (!check_pat_args_are_sane(xe, &madvise_range,
> + args->pat_index.val)) {
> + err = -EINVAL;
> + goto free_vmas;
> + }
> + }
> +
> if (madvise_range.has_bo_vmas) {
> if (args->type == DRM_XE_MEM_RANGE_ATTR_ATOMIC) {
> if (!check_bo_args_are_sane(vm, madvise_range.vmas,
> madvise_range.num_vmas,
> args->atomic.val)) {
> err = -EINVAL;
> - goto madv_fini;
> + goto free_vmas;
> }
> }
>
> @@ -485,8 +530,8 @@ int xe_vm_madvise_ioctl(struct drm_device *dev, void *data, struct drm_file *fil
> err_fini:
> if (madvise_range.has_bo_vmas)
> drm_exec_fini(&exec);
> +free_vmas:
> kfree(madvise_range.vmas);
> - madvise_range.vmas = NULL;
> madv_fini:
> xe_madvise_details_fini(&details);
> unlock_vm:
^ permalink raw reply [flat|nested] 20+ messages in thread
* RE: [PATCH v4] drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise
2026-02-03 16:38 ` Matthew Auld
@ 2026-02-03 16:59 ` Yao, Jia
0 siblings, 0 replies; 20+ messages in thread
From: Yao, Jia @ 2026-02-03 16:59 UTC (permalink / raw)
To: Auld, Matthew, intel-xe@lists.freedesktop.org
Cc: stable@vger.kernel.org, Lin, Shuicheng, Mathew, Alwin,
Mrozek, Michal, Brost, Matthew
I prefer a separate patch to get it landed ASAP. For this one, need clarify the situation with CI, for this patch and the changes in IGT are interdependent.
> -----Original Message-----
> From: Auld, Matthew <matthew.auld@intel.com>
> Sent: Tuesday, February 3, 2026 8:39 AM
> To: Yao, Jia <jia.yao@intel.com>; intel-xe@lists.freedesktop.org
> Cc: stable@vger.kernel.org; Lin, Shuicheng <shuicheng.lin@intel.com>;
> Mathew, Alwin <alwin.mathew@intel.com>; Mrozek, Michal
> <michal.mrozek@intel.com>; Brost, Matthew <matthew.brost@intel.com>
> Subject: Re: [PATCH v4] drm/xe/uapi: Reject coh_none PAT index for CPU
> cached memory in madvise
>
> On 03/02/2026 15:48, Jia Yao wrote:
> > Add validation in xe_vm_madvise_ioctl() to reject PAT indices with
> > XE_COH_NONE coherency mode when applied to CPU cached memory.
> >
> > Using coh_none with CPU cached buffers is a security issue. When the
> > kernel clears pages before reallocation, the clear operation stays in
> > CPU cache (dirty). GPU with coh_none can bypass CPU caches and read
> > stale sensitive data directly from DRAM, potentially leaking data from
> > previously freed pages of other processes.
> >
> > This aligns with the existing validation in vm_bind path
> > (xe_vm_bind_ioctl_validate_bo).
> >
> > v2(Matthew brost)
> > - Add fixes
> > - Move one debug print to better place
> >
> > v3(Matthew Auld)
> > - Should be drm/xe/uapi
> > - More Cc
> >
> > v4(Shuicheng Lin)
> > - Fix kmem leak issues by the way
> >
> > Fixes: ada7486c5668 ("drm/xe: Implement madvise ioctl for xe")
> > Cc: stable@vger.kernel.org # v6.18
> > Cc: Shuicheng Lin <shuicheng.lin@intel.com>
> > Cc: Mathew Alwin <alwin.mathew@intel.com>
> > Cc: Michal Mrozek <michal.mrozek@intel.com>
> > Cc: Matthew Brost <matthew.brost@intel.com>
> > Cc: Matthew Auld <matthew.auld@intel.com>
> > Signed-off-by: Jia Yao <jia.yao@intel.com>
>
> Unless I'm blind, it looks like there is some missing validation on the pat_index
> coming from userspace also, where we can trigger OOB kernel read when
> calling get_coh_mode(), if malicious user gives you a bogus too large index. I
> think we need to fix that also, maybe as a seperate patch in this series or just
> send as seperate fix and get it landed ASAP?
>
> > ---
> > drivers/gpu/drm/xe/xe_vm_madvise.c | 55
> +++++++++++++++++++++++++++---
> > 1 file changed, 50 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/xe/xe_vm_madvise.c
> > b/drivers/gpu/drm/xe/xe_vm_madvise.c
> > index add9a6ca2390..bf41fe75a336 100644
> > --- a/drivers/gpu/drm/xe/xe_vm_madvise.c
> > +++ b/drivers/gpu/drm/xe/xe_vm_madvise.c
> > @@ -74,7 +74,7 @@ static int get_vmas(struct xe_vm *vm, struct
> xe_vmas_in_madvise_range *madvise_r
> > }
> >
> > madvise_range->vmas[madvise_range->num_vmas] = vma;
> > - (madvise_range->num_vmas)++;
> > + madvise_range->num_vmas++;
> > }
> >
> > if (!madvise_range->num_vmas)
> > @@ -352,6 +352,43 @@ static void xe_madvise_details_fini(struct
> xe_madvise_details *details)
> > drm_pagemap_put(details->dpagemap);
> > }
> >
> > +static bool check_pat_args_are_sane(struct xe_device *xe,
> > + struct xe_vmas_in_madvise_range
> *madvise_range,
> > + u16 pat_index)
> > +{
> > + u16 coh_mode = xe_pat_index_get_coh_mode(xe, pat_index);
> > + int i;
> > +
> > + /*
> > + * Using coh_none with CPU cached buffers is not allowed.
> > + * Otherwise CPU page clearing can be bypassed, which is a
> > + * security issue. GPU can directly access system memory and
> > + * bypass CPU caches, potentially reading stale sensitive data
> > + * from previously freed pages.
> > + */
> > + if (coh_mode != XE_COH_NONE)
> > + return true;
> > +
> > + for (i = 0; i < madvise_range->num_vmas; i++) {
> > + struct xe_vma *vma = madvise_range->vmas[i];
> > + struct xe_bo *bo = xe_vma_bo(vma);
> > +
> > + if (bo) {
> > + /* BO with WB caching + COH_NONE is not allowed */
> > + if (XE_IOCTL_DBG(xe, bo->cpu_caching ==
> DRM_XE_GEM_CPU_CACHING_WB))
> > + return false;
> > + /* Imported dma-buf without caching info, assume
> cached */
> > + if (XE_IOCTL_DBG(xe, !bo->cpu_caching))
> > + return false;
> > + } else if (XE_IOCTL_DBG(xe, xe_vma_is_cpu_addr_mirror(vma)
> ||
> > + xe_vma_is_userptr(vma)))
> > + /* System memory (userptr/SVM) is always CPU
> cached */
> > + return false;
> > + }
> > +
> > + return true;
> > +}
> > +
> > static bool check_bo_args_are_sane(struct xe_vm *vm, struct xe_vma
> **vmas,
> > int num_vmas, u32 atomic_val)
> > {
> > @@ -388,12 +425,12 @@ static bool check_bo_args_are_sane(struct
> xe_vm *vm, struct xe_vma **vmas,
> > return true;
> > }
> > /**
> > - * xe_vm_madvise_ioctl - Handle MADVise ioctl for a VM
> > + * xe_vm_madvise_ioctl - Handle madvise ioctl for a VM
> > * @dev: DRM device pointer
> > * @data: Pointer to ioctl data (drm_xe_madvise*)
> > * @file: DRM file pointer
> > *
> > - * Handles the MADVISE ioctl to provide memory advice for vma's
> > within
> > + * Handles the madvise ioctl to provide memory advice for vma's
> > + within
> > * input range.
> > *
> > * Return: 0 on success or a negative error code on failure.
> > @@ -442,13 +479,21 @@ int xe_vm_madvise_ioctl(struct drm_device *dev,
> void *data, struct drm_file *fil
> > if (err || !madvise_range.num_vmas)
> > goto madv_fini;
> >
> > + if (args->type == DRM_XE_MEM_RANGE_ATTR_PAT) {
> > + if (!check_pat_args_are_sane(xe, &madvise_range,
> > + args->pat_index.val)) {
> > + err = -EINVAL;
> > + goto free_vmas;
> > + }
> > + }
> > +
> > if (madvise_range.has_bo_vmas) {
> > if (args->type == DRM_XE_MEM_RANGE_ATTR_ATOMIC) {
> > if (!check_bo_args_are_sane(vm,
> madvise_range.vmas,
> > madvise_range.num_vmas,
> > args->atomic.val)) {
> > err = -EINVAL;
> > - goto madv_fini;
> > + goto free_vmas;
> > }
> > }
> >
> > @@ -485,8 +530,8 @@ int xe_vm_madvise_ioctl(struct drm_device *dev,
> void *data, struct drm_file *fil
> > err_fini:
> > if (madvise_range.has_bo_vmas)
> > drm_exec_fini(&exec);
> > +free_vmas:
> > kfree(madvise_range.vmas);
> > - madvise_range.vmas = NULL;
> > madv_fini:
> > xe_madvise_details_fini(&details);
> > unlock_vm:
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3] drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise
2026-01-30 22:07 ` [PATCH v3] drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise Jia Yao
2026-02-03 2:54 ` Lin, Shuicheng
@ 2026-02-04 15:13 ` Souza, Jose
1 sibling, 0 replies; 20+ messages in thread
From: Souza, Jose @ 2026-02-04 15:13 UTC (permalink / raw)
To: intel-xe@lists.freedesktop.org, Yao, Jia
Cc: Brost, Matthew, stable@vger.kernel.org, Auld, Matthew,
Mathew, Alwin, Mrozek, Michal
On Fri, 2026-01-30 at 22:07 +0000, Jia Yao wrote:
> Add validation in xe_vm_madvise_ioctl() to reject PAT indices with
> XE_COH_NONE coherency mode when applied to CPU cached memory.
>
> Using coh_none with CPU cached buffers is a security issue. When the
> kernel clears pages before reallocation, the clear operation stays in
> CPU cache (dirty). GPU with coh_none can bypass CPU caches and read
> stale sensitive data directly from DRAM, potentially leaking data
> from
> previously freed pages of other processes.
>
> This aligns with the existing validation in vm_bind path
> (xe_vm_bind_ioctl_validate_bo).
>
> v2(Matthew brost)
> - Add fixes
> - Move one debug print to better place
>
> v3(Matthew Auld)
> - Should be drm/xe/uapi
> - More Cc
>
> Fixes: ada7486c5668 ("drm/xe: Implement madvise ioctl for xe")
> Cc: stable@vger.kernel.org # v6.18
> Cc: Mathew Alwin <alwin.mathew@intel.com>
> Cc: Michal Mrozek <michal.mrozek@intel.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
> Cc: Matthew Auld <matthew.auld@intel.com>
Mesa don't use madvise but API but the restriction makes sense, the API
changes is
Acked-by: José Roberto de Souza <jose.souza@intel.com>
> Signed-off-by: Jia Yao <jia.yao@intel.com>
> ---
> drivers/gpu/drm/xe/xe_vm_madvise.c | 47
> ++++++++++++++++++++++++++++++
> 1 file changed, 47 insertions(+)
>
> diff --git a/drivers/gpu/drm/xe/xe_vm_madvise.c
> b/drivers/gpu/drm/xe/xe_vm_madvise.c
> index add9a6ca2390..50b82e821da7 100644
> --- a/drivers/gpu/drm/xe/xe_vm_madvise.c
> +++ b/drivers/gpu/drm/xe/xe_vm_madvise.c
> @@ -352,6 +352,44 @@ static void xe_madvise_details_fini(struct
> xe_madvise_details *details)
> drm_pagemap_put(details->dpagemap);
> }
>
> +static bool check_pat_args_are_sane(struct xe_device *xe,
> + struct xe_vmas_in_madvise_range
> *madvise_range,
> + u16 pat_index)
> +{
> + u16 coh_mode = xe_pat_index_get_coh_mode(xe, pat_index);
> + int i;
> +
> + /*
> + * Using coh_none with CPU cached buffers is not allowed.
> + * Otherwise CPU page clearing can be bypassed, which is a
> + * security issue. GPU can directly access system memory and
> + * bypass CPU caches, potentially reading stale sensitive
> data
> + * from previously freed pages.
> + */
> + if (coh_mode != XE_COH_NONE)
> + return true;
> +
> + for (i = 0; i < madvise_range->num_vmas; i++) {
> + struct xe_vma *vma = madvise_range->vmas[i];
> + struct xe_bo *bo = xe_vma_bo(vma);
> +
> + if (bo) {
> + /* BO with WB caching + COH_NONE is not
> allowed */
> + if (XE_IOCTL_DBG(xe, bo->cpu_caching ==
> DRM_XE_GEM_CPU_CACHING_WB))
> + return false;
> + /* Imported dma-buf without caching info,
> assume cached */
> + if (XE_IOCTL_DBG(xe, !bo->cpu_caching))
> + return false;
> + } else if (XE_IOCTL_DBG(xe,
> xe_vma_is_cpu_addr_mirror(vma)) ||
> + xe_vma_is_userptr(vma)) {
> + /* System memory (userptr/SVM) is always CPU
> cached */
> + return false;
> + }
> + }
> +
> + return true;
> +}
> +
> static bool check_bo_args_are_sane(struct xe_vm *vm, struct xe_vma
> **vmas,
> int num_vmas, u32 atomic_val)
> {
> @@ -442,6 +480,14 @@ int xe_vm_madvise_ioctl(struct drm_device *dev,
> void *data, struct drm_file *fil
> if (err || !madvise_range.num_vmas)
> goto madv_fini;
>
> + if (args->type == DRM_XE_MEM_RANGE_ATTR_PAT) {
> + if (!check_pat_args_are_sane(xe, &madvise_range,
> + args->pat_index.val)) {
> + err = -EINVAL;
> + goto free_vmas;
> + }
> + }
> +
> if (madvise_range.has_bo_vmas) {
> if (args->type == DRM_XE_MEM_RANGE_ATTR_ATOMIC) {
> if (!check_bo_args_are_sane(vm,
> madvise_range.vmas,
> @@ -485,6 +531,7 @@ int xe_vm_madvise_ioctl(struct drm_device *dev,
> void *data, struct drm_file *fil
> err_fini:
> if (madvise_range.has_bo_vmas)
> drm_exec_fini(&exec);
> +free_vmas:
> kfree(madvise_range.vmas);
> madvise_range.vmas = NULL;
> madv_fini:
^ permalink raw reply [flat|nested] 20+ messages in thread
* RE: [PATCH v4] drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise
2026-02-03 15:48 ` [PATCH v4] " Jia Yao
2026-02-03 16:38 ` Matthew Auld
@ 2026-03-10 14:50 ` Mrozek, Michal
1 sibling, 0 replies; 20+ messages in thread
From: Mrozek, Michal @ 2026-03-10 14:50 UTC (permalink / raw)
To: Yao, Jia, intel-xe@lists.freedesktop.org
Cc: stable@vger.kernel.org, Lin, Shuicheng, Mathew, Alwin,
Brost, Matthew, Auld, Matthew
Acked-by: Michal Mrozek <michal.mrozek@intel.com>
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v5 0/2] drm/xe: PAT index validation for CPU_ADDR_MIRROR and
[not found] <20260129000147.339361-1-jia.yao@intel.com>
2026-01-30 22:07 ` [PATCH v3] drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise Jia Yao
2026-02-03 15:48 ` [PATCH v4] " Jia Yao
@ 2026-03-16 7:22 ` Jia Yao
2026-03-16 7:22 ` [PATCH v5 1/2] drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise Jia Yao
2026-03-16 7:22 ` [PATCH v5 2/2] drm/xe: Reject coh_none PAT index for CPU_ADDR_MIRROR Jia Yao
2026-03-16 16:42 ` [PATCH v5 0/2] drm/xe: PAT index validation for CPU_ADDR_MIRROR and madvise Jia Yao
2026-03-19 11:58 ` [PATCH v7 0/2] drm/xe: PAT index validation for CPU_ADDR_MIRROR and madvise Jia Yao
4 siblings, 2 replies; 20+ messages in thread
From: Jia Yao @ 2026-03-16 7:22 UTC (permalink / raw)
To: intel-xe
Cc: Jia Yao, stable, Shuicheng Lin, Mathew Alwin, Michal Mrozek,
Matthew Brost, Matthew Auld
This patch series strengthens PAT index validation to reject unsafe
configurations for CPU cached memory, fixing a potential security issue
where GPU could bypass CPU caches and read stale sensitive data.
The first patch adds validation to the madvise ioctl path, rejecting
XE_COH_NONE PAT indices when applied to CPU cached buffers (including
CPU address mirror and userptr mappings).
The second patch extends this validation to the vm_bind ioctl path,
ensuring DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR is treated the same as
DRM_XE_VM_BIND_OP_MAP_USERPTR with respect to PAT index requirements.
Fixes: ada7486c5668 ("drm/xe: Implement madvise ioctl for xe")
Cc: stable@vger.kernel.org # v6.18
Cc: Shuicheng Lin <shuicheng.lin@intel.com>
Cc: Mathew Alwin <alwin.mathew@intel.com>
Cc: Michal Mrozek <michal.mrozek@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
Jia Yao (2):
drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in
madvise
drm/xe: Reject coh_none PAT index for CPU_ADDR_MIRROR
drivers/gpu/drm/xe/xe_vm.c | 2 +-
drivers/gpu/drm/xe/xe_vm_madvise.c | 46 +++++++++++++++++++++++++++++-
2 files changed, 46 insertions(+), 2 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v5 1/2] drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise
2026-03-16 7:22 ` [PATCH v5 0/2] drm/xe: PAT index validation for CPU_ADDR_MIRROR and Jia Yao
@ 2026-03-16 7:22 ` Jia Yao
2026-03-16 10:59 ` Matthew Auld
2026-03-16 7:22 ` [PATCH v5 2/2] drm/xe: Reject coh_none PAT index for CPU_ADDR_MIRROR Jia Yao
1 sibling, 1 reply; 20+ messages in thread
From: Jia Yao @ 2026-03-16 7:22 UTC (permalink / raw)
To: intel-xe
Cc: Jia Yao, stable, Shuicheng Lin, Mathew Alwin, Michal Mrozek,
Matthew Brost, Matthew Auld, José Roberto de Souza
Add validation in xe_vm_madvise_ioctl() to reject PAT indices with
XE_COH_NONE coherency mode when applied to CPU cached memory.
Using coh_none with CPU cached buffers is a security issue. When the
kernel clears pages before reallocation, the clear operation stays in
CPU cache (dirty). GPU with coh_none can bypass CPU caches and read
stale sensitive data directly from DRAM, potentially leaking data from
previously freed pages of other processes.
This aligns with the existing validation in vm_bind path
(xe_vm_bind_ioctl_validate_bo).
v2(Matthew brost)
- Add fixes
- Move one debug print to better place
v3(Matthew Auld)
- Should be drm/xe/uapi
- More Cc
v4(Shuicheng Lin)
- Fix kmem leak issues by the way
v5
- Remove kmem leak because it has been merged by other patch
Fixes: ada7486c5668 ("drm/xe: Implement madvise ioctl for xe")
Cc: stable@vger.kernel.org # v6.18
Cc: Shuicheng Lin <shuicheng.lin@intel.com>
Cc: Mathew Alwin <alwin.mathew@intel.com>
Cc: Michal Mrozek <michal.mrozek@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Jia Yao <jia.yao@intel.com>
Acked-by: Michal Mrozek <michal.mrozek@intel.com>
Acked-by: José Roberto de Souza <jose.souza@intel.com>
---
drivers/gpu/drm/xe/xe_vm_madvise.c | 46 +++++++++++++++++++++++++++++-
1 file changed, 45 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/xe/xe_vm_madvise.c b/drivers/gpu/drm/xe/xe_vm_madvise.c
index 869db304d96d..5d0acaad924c 100644
--- a/drivers/gpu/drm/xe/xe_vm_madvise.c
+++ b/drivers/gpu/drm/xe/xe_vm_madvise.c
@@ -365,6 +365,43 @@ static void xe_madvise_details_fini(struct xe_madvise_details *details)
drm_pagemap_put(details->dpagemap);
}
+static bool check_pat_args_are_sane(struct xe_device *xe,
+ struct xe_vmas_in_madvise_range *madvise_range,
+ u16 pat_index)
+{
+ u16 coh_mode = xe_pat_index_get_coh_mode(xe, pat_index);
+ int i;
+
+ /*
+ * Using coh_none with CPU cached buffers is not allowed.
+ * Otherwise CPU page clearing can be bypassed, which is a
+ * security issue. GPU can directly access system memory and
+ * bypass CPU caches, potentially reading stale sensitive data
+ * from previously freed pages.
+ */
+ if (coh_mode != XE_COH_NONE)
+ return true;
+
+ for (i = 0; i < madvise_range->num_vmas; i++) {
+ struct xe_vma *vma = madvise_range->vmas[i];
+ struct xe_bo *bo = xe_vma_bo(vma);
+
+ if (bo) {
+ /* BO with WB caching + COH_NONE is not allowed */
+ if (XE_IOCTL_DBG(xe, bo->cpu_caching == DRM_XE_GEM_CPU_CACHING_WB))
+ return false;
+ /* Imported dma-buf without caching info, assume cached */
+ if (XE_IOCTL_DBG(xe, !bo->cpu_caching))
+ return false;
+ } else if (XE_IOCTL_DBG(xe, xe_vma_is_cpu_addr_mirror(vma) ||
+ xe_vma_is_userptr(vma)))
+ /* System memory (userptr/SVM) is always CPU cached */
+ return false;
+ }
+
+ return true;
+}
+
static bool check_bo_args_are_sane(struct xe_vm *vm, struct xe_vma **vmas,
int num_vmas, u32 atomic_val)
{
@@ -455,6 +492,14 @@ int xe_vm_madvise_ioctl(struct drm_device *dev, void *data, struct drm_file *fil
if (err || !madvise_range.num_vmas)
goto madv_fini;
+ if (args->type == DRM_XE_MEM_RANGE_ATTR_PAT) {
+ if (!check_pat_args_are_sane(xe, &madvise_range,
+ args->pat_index.val)) {
+ err = -EINVAL;
+ goto free_vmas;
+ }
+ }
+
if (madvise_range.has_bo_vmas) {
if (args->type == DRM_XE_MEM_RANGE_ATTR_ATOMIC) {
if (!check_bo_args_are_sane(vm, madvise_range.vmas,
@@ -500,7 +545,6 @@ int xe_vm_madvise_ioctl(struct drm_device *dev, void *data, struct drm_file *fil
drm_exec_fini(&exec);
free_vmas:
kfree(madvise_range.vmas);
- madvise_range.vmas = NULL;
madv_fini:
xe_madvise_details_fini(&details);
unlock_vm:
--
2.43.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v5 2/2] drm/xe: Reject coh_none PAT index for CPU_ADDR_MIRROR
2026-03-16 7:22 ` [PATCH v5 0/2] drm/xe: PAT index validation for CPU_ADDR_MIRROR and Jia Yao
2026-03-16 7:22 ` [PATCH v5 1/2] drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise Jia Yao
@ 2026-03-16 7:22 ` Jia Yao
2026-03-16 11:40 ` Matthew Auld
1 sibling, 1 reply; 20+ messages in thread
From: Jia Yao @ 2026-03-16 7:22 UTC (permalink / raw)
To: intel-xe
Cc: Jia Yao, stable, Shuicheng Lin, Mathew Alwin, Michal Mrozek,
Matthew Brost, Matthew Auld
Add validation in xe_vm_bind_ioctl() to reject PAT indices with
XE_COH_NONE coherency mode when used with
DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR, consistent with the existing
validation for DRM_XE_VM_BIND_OP_MAP_USERPTR.
CPU address mirror mappings use system memory which is CPU cached,
making them incompatible with COH_NONE PAT index. Using COH_NONE with
CPU cached buffers is a security issue: GPU can bypass CPU caches and
directly read stale sensitive data from DRAM, potentially leaking data
from previously freed pages.
Although CPU_ADDR_MIRROR mappings don't create actual memory mappings
(the range is reserved for dynamic mapping on GPU page faults), the
underlying system memory is still CPU cached, so the same PAT coherency
restrictions as MAP_USERPTR should apply.
Fixes: ada7486c5668 ("drm/xe: Implement madvise ioctl for xe")
Cc: stable@vger.kernel.org # v6.18
Cc: Shuicheng Lin <shuicheng.lin@intel.com>
Cc: Mathew Alwin <alwin.mathew@intel.com>
Cc: Michal Mrozek <michal.mrozek@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Jia Yao <jia.yao@intel.com>
---
drivers/gpu/drm/xe/xe_vm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index 5572e12c2a7e..1c4b4a5eeadb 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -3491,7 +3491,7 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe, struct xe_vm *vm,
XE_IOCTL_DBG(xe, obj &&
op == DRM_XE_VM_BIND_OP_MAP_USERPTR) ||
XE_IOCTL_DBG(xe, coh_mode == XE_COH_NONE &&
- op == DRM_XE_VM_BIND_OP_MAP_USERPTR) ||
+ (op == DRM_XE_VM_BIND_OP_MAP_USERPTR || is_cpu_addr_mirror)) ||
XE_IOCTL_DBG(xe, comp_en &&
op == DRM_XE_VM_BIND_OP_MAP_USERPTR) ||
XE_IOCTL_DBG(xe, op == DRM_XE_VM_BIND_OP_MAP_USERPTR &&
--
2.43.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v5 1/2] drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise
2026-03-16 7:22 ` [PATCH v5 1/2] drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise Jia Yao
@ 2026-03-16 10:59 ` Matthew Auld
2026-03-16 15:29 ` Lin, Shuicheng
0 siblings, 1 reply; 20+ messages in thread
From: Matthew Auld @ 2026-03-16 10:59 UTC (permalink / raw)
To: Jia Yao, intel-xe
Cc: stable, Shuicheng Lin, Mathew Alwin, Michal Mrozek, Matthew Brost,
José Roberto de Souza
On 16/03/2026 07:22, Jia Yao wrote:
> Add validation in xe_vm_madvise_ioctl() to reject PAT indices with
> XE_COH_NONE coherency mode when applied to CPU cached memory.
>
> Using coh_none with CPU cached buffers is a security issue. When the
> kernel clears pages before reallocation, the clear operation stays in
> CPU cache (dirty). GPU with coh_none can bypass CPU caches and read
> stale sensitive data directly from DRAM, potentially leaking data from
> previously freed pages of other processes.
>
> This aligns with the existing validation in vm_bind path
> (xe_vm_bind_ioctl_validate_bo).
>
> v2(Matthew brost)
> - Add fixes
> - Move one debug print to better place
>
> v3(Matthew Auld)
> - Should be drm/xe/uapi
> - More Cc
>
> v4(Shuicheng Lin)
> - Fix kmem leak issues by the way
>
> v5
> - Remove kmem leak because it has been merged by other patch
>
> Fixes: ada7486c5668 ("drm/xe: Implement madvise ioctl for xe")
> Cc: stable@vger.kernel.org # v6.18
> Cc: Shuicheng Lin <shuicheng.lin@intel.com>
> Cc: Mathew Alwin <alwin.mathew@intel.com>
> Cc: Michal Mrozek <michal.mrozek@intel.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
> Cc: Matthew Auld <matthew.auld@intel.com>
> Signed-off-by: Jia Yao <jia.yao@intel.com>
> Acked-by: Michal Mrozek <michal.mrozek@intel.com>
> Acked-by: José Roberto de Souza <jose.souza@intel.com>
> ---
> drivers/gpu/drm/xe/xe_vm_madvise.c | 46 +++++++++++++++++++++++++++++-
> 1 file changed, 45 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_vm_madvise.c b/drivers/gpu/drm/xe/xe_vm_madvise.c
> index 869db304d96d..5d0acaad924c 100644
> --- a/drivers/gpu/drm/xe/xe_vm_madvise.c
> +++ b/drivers/gpu/drm/xe/xe_vm_madvise.c
> @@ -365,6 +365,43 @@ static void xe_madvise_details_fini(struct xe_madvise_details *details)
> drm_pagemap_put(details->dpagemap);
> }
>
> +static bool check_pat_args_are_sane(struct xe_device *xe,
> + struct xe_vmas_in_madvise_range *madvise_range,
> + u16 pat_index)
> +{
> + u16 coh_mode = xe_pat_index_get_coh_mode(xe, pat_index);
> + int i;
> +
> + /*
> + * Using coh_none with CPU cached buffers is not allowed.
> + * Otherwise CPU page clearing can be bypassed, which is a
> + * security issue. GPU can directly access system memory and
> + * bypass CPU caches, potentially reading stale sensitive data
> + * from previously freed pages.
> + */
> + if (coh_mode != XE_COH_NONE)
> + return true;
> +
> + for (i = 0; i < madvise_range->num_vmas; i++) {
> + struct xe_vma *vma = madvise_range->vmas[i];
> + struct xe_bo *bo = xe_vma_bo(vma);
> +
> + if (bo) {
> + /* BO with WB caching + COH_NONE is not allowed */
> + if (XE_IOCTL_DBG(xe, bo->cpu_caching == DRM_XE_GEM_CPU_CACHING_WB))
> + return false;
> + /* Imported dma-buf without caching info, assume cached */
> + if (XE_IOCTL_DBG(xe, !bo->cpu_caching))
> + return false;
> + } else if (XE_IOCTL_DBG(xe, xe_vma_is_cpu_addr_mirror(vma) ||
> + xe_vma_is_userptr(vma)))
> + /* System memory (userptr/SVM) is always CPU cached */
> + return false;
> + }
> +
> + return true;
> +}
> +
> static bool check_bo_args_are_sane(struct xe_vm *vm, struct xe_vma **vmas,
> int num_vmas, u32 atomic_val)
> {
> @@ -455,6 +492,14 @@ int xe_vm_madvise_ioctl(struct drm_device *dev, void *data, struct drm_file *fil
> if (err || !madvise_range.num_vmas)
> goto madv_fini;
>
> + if (args->type == DRM_XE_MEM_RANGE_ATTR_PAT) {
> + if (!check_pat_args_are_sane(xe, &madvise_range,
> + args->pat_index.val)) {
> + err = -EINVAL;
> + goto free_vmas;
> + }
> + }
> +
> if (madvise_range.has_bo_vmas) {
> if (args->type == DRM_XE_MEM_RANGE_ATTR_ATOMIC) {
> if (!check_bo_args_are_sane(vm, madvise_range.vmas,
> @@ -500,7 +545,6 @@ int xe_vm_madvise_ioctl(struct drm_device *dev, void *data, struct drm_file *fil
> drm_exec_fini(&exec);
> free_vmas:
> kfree(madvise_range.vmas);
> - madvise_range.vmas = NULL;
Do we really need this change?
Otherwise,
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
> madv_fini:
> xe_madvise_details_fini(&details);
> unlock_vm:
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v5 2/2] drm/xe: Reject coh_none PAT index for CPU_ADDR_MIRROR
2026-03-16 7:22 ` [PATCH v5 2/2] drm/xe: Reject coh_none PAT index for CPU_ADDR_MIRROR Jia Yao
@ 2026-03-16 11:40 ` Matthew Auld
0 siblings, 0 replies; 20+ messages in thread
From: Matthew Auld @ 2026-03-16 11:40 UTC (permalink / raw)
To: Jia Yao, intel-xe
Cc: stable, Shuicheng Lin, Mathew Alwin, Michal Mrozek, Matthew Brost
On 16/03/2026 07:22, Jia Yao wrote:
> Add validation in xe_vm_bind_ioctl() to reject PAT indices with
> XE_COH_NONE coherency mode when used with
> DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR, consistent with the existing
> validation for DRM_XE_VM_BIND_OP_MAP_USERPTR.
>
> CPU address mirror mappings use system memory which is CPU cached,
> making them incompatible with COH_NONE PAT index. Using COH_NONE with
> CPU cached buffers is a security issue: GPU can bypass CPU caches and
> directly read stale sensitive data from DRAM, potentially leaking data
> from previously freed pages.
>
> Although CPU_ADDR_MIRROR mappings don't create actual memory mappings
> (the range is reserved for dynamic mapping on GPU page faults), the
> underlying system memory is still CPU cached, so the same PAT coherency
> restrictions as MAP_USERPTR should apply.
>
> Fixes: ada7486c5668 ("drm/xe: Implement madvise ioctl for xe")
Is this the right fixes tag?
> Cc: stable@vger.kernel.org # v6.18
> Cc: Shuicheng Lin <shuicheng.lin@intel.com>
> Cc: Mathew Alwin <alwin.mathew@intel.com>
> Cc: Michal Mrozek <michal.mrozek@intel.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
> Cc: Matthew Auld <matthew.auld@intel.com>
> Signed-off-by: Jia Yao <jia.yao@intel.com>
As discussed offline, I think this is needed. My understanding is that
when binding an svm range we use the parent vma pat index, and without
using the madvise pat control, the default pat index is whatever the
user selects here, which could be incoherent, and on least igpu that
will be problematic when accessing CPU cached system memory.
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
> ---
> drivers/gpu/drm/xe/xe_vm.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
> index 5572e12c2a7e..1c4b4a5eeadb 100644
> --- a/drivers/gpu/drm/xe/xe_vm.c
> +++ b/drivers/gpu/drm/xe/xe_vm.c
> @@ -3491,7 +3491,7 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe, struct xe_vm *vm,
> XE_IOCTL_DBG(xe, obj &&
> op == DRM_XE_VM_BIND_OP_MAP_USERPTR) ||
> XE_IOCTL_DBG(xe, coh_mode == XE_COH_NONE &&
> - op == DRM_XE_VM_BIND_OP_MAP_USERPTR) ||
> + (op == DRM_XE_VM_BIND_OP_MAP_USERPTR || is_cpu_addr_mirror)) ||
> XE_IOCTL_DBG(xe, comp_en &&
> op == DRM_XE_VM_BIND_OP_MAP_USERPTR) ||
> XE_IOCTL_DBG(xe, op == DRM_XE_VM_BIND_OP_MAP_USERPTR &&
^ permalink raw reply [flat|nested] 20+ messages in thread
* RE: [PATCH v5 1/2] drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise
2026-03-16 10:59 ` Matthew Auld
@ 2026-03-16 15:29 ` Lin, Shuicheng
0 siblings, 0 replies; 20+ messages in thread
From: Lin, Shuicheng @ 2026-03-16 15:29 UTC (permalink / raw)
To: Auld, Matthew, Yao, Jia, intel-xe@lists.freedesktop.org
Cc: stable@vger.kernel.org, Mathew, Alwin, Mrozek, Michal,
Brost, Matthew, Souza, Jose
On Mon, Mar 16, 2026 3:59 AM Matthew Auld wrote:
> On 16/03/2026 07:22, Jia Yao wrote:
> > Add validation in xe_vm_madvise_ioctl() to reject PAT indices with
> > XE_COH_NONE coherency mode when applied to CPU cached memory.
> >
> > Using coh_none with CPU cached buffers is a security issue. When the
> > kernel clears pages before reallocation, the clear operation stays in
> > CPU cache (dirty). GPU with coh_none can bypass CPU caches and read
> > stale sensitive data directly from DRAM, potentially leaking data from
> > previously freed pages of other processes.
> >
> > This aligns with the existing validation in vm_bind path
> > (xe_vm_bind_ioctl_validate_bo).
> >
> > v2(Matthew brost)
> > - Add fixes
> > - Move one debug print to better place
> >
> > v3(Matthew Auld)
> > - Should be drm/xe/uapi
> > - More Cc
> >
> > v4(Shuicheng Lin)
> > - Fix kmem leak issues by the way
It is better to fix issue with different patch, as they should have different Fixes tag.
> >
> > v5
> > - Remove kmem leak because it has been merged by other patch
s/other/another
> >
> > Fixes: ada7486c5668 ("drm/xe: Implement madvise ioctl for xe")
> > Cc: stable@vger.kernel.org # v6.18
> > Cc: Shuicheng Lin <shuicheng.lin@intel.com>
> > Cc: Mathew Alwin <alwin.mathew@intel.com>
> > Cc: Michal Mrozek <michal.mrozek@intel.com>
> > Cc: Matthew Brost <matthew.brost@intel.com>
> > Cc: Matthew Auld <matthew.auld@intel.com>
> > Signed-off-by: Jia Yao <jia.yao@intel.com>
> > Acked-by: Michal Mrozek <michal.mrozek@intel.com>
> > Acked-by: José Roberto de Souza <jose.souza@intel.com>
> > ---
> > drivers/gpu/drm/xe/xe_vm_madvise.c | 46
> +++++++++++++++++++++++++++++-
> > 1 file changed, 45 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/xe/xe_vm_madvise.c
> > b/drivers/gpu/drm/xe/xe_vm_madvise.c
> > index 869db304d96d..5d0acaad924c 100644
> > --- a/drivers/gpu/drm/xe/xe_vm_madvise.c
> > +++ b/drivers/gpu/drm/xe/xe_vm_madvise.c
> > @@ -365,6 +365,43 @@ static void xe_madvise_details_fini(struct
> xe_madvise_details *details)
> > drm_pagemap_put(details->dpagemap);
> > }
> >
> > +static bool check_pat_args_are_sane(struct xe_device *xe,
> > + struct xe_vmas_in_madvise_range
> *madvise_range,
> > + u16 pat_index)
> > +{
> > + u16 coh_mode = xe_pat_index_get_coh_mode(xe, pat_index);
> > + int i;
> > +
> > + /*
> > + * Using coh_none with CPU cached buffers is not allowed.
> > + * Otherwise CPU page clearing can be bypassed, which is a
> > + * security issue. GPU can directly access system memory and
> > + * bypass CPU caches, potentially reading stale sensitive data
> > + * from previously freed pages.
> > + */
> > + if (coh_mode != XE_COH_NONE)
> > + return true;
> > +
> > + for (i = 0; i < madvise_range->num_vmas; i++) {
> > + struct xe_vma *vma = madvise_range->vmas[i];
> > + struct xe_bo *bo = xe_vma_bo(vma);
> > +
> > + if (bo) {
> > + /* BO with WB caching + COH_NONE is not allowed */
> > + if (XE_IOCTL_DBG(xe, bo->cpu_caching ==
> DRM_XE_GEM_CPU_CACHING_WB))
> > + return false;
> > + /* Imported dma-buf without caching info, assume
> cached */
> > + if (XE_IOCTL_DBG(xe, !bo->cpu_caching))
> > + return false;
> > + } else if (XE_IOCTL_DBG(xe, xe_vma_is_cpu_addr_mirror(vma)
> ||
> > + xe_vma_is_userptr(vma)))
> > + /* System memory (userptr/SVM) is always CPU
> cached */
> > + return false;
> > + }
> > +
> > + return true;
> > +}
> > +
> > static bool check_bo_args_are_sane(struct xe_vm *vm, struct xe_vma
> **vmas,
> > int num_vmas, u32 atomic_val)
> > {
> > @@ -455,6 +492,14 @@ int xe_vm_madvise_ioctl(struct drm_device *dev,
> void *data, struct drm_file *fil
> > if (err || !madvise_range.num_vmas)
> > goto madv_fini;
> >
> > + if (args->type == DRM_XE_MEM_RANGE_ATTR_PAT) {
> > + if (!check_pat_args_are_sane(xe, &madvise_range,
> > + args->pat_index.val)) {
> > + err = -EINVAL;
> > + goto free_vmas;
> > + }
> > + }
> > +
> > if (madvise_range.has_bo_vmas) {
> > if (args->type == DRM_XE_MEM_RANGE_ATTR_ATOMIC) {
> > if (!check_bo_args_are_sane(vm,
> madvise_range.vmas, @@ -500,7
> > +545,6 @@ int xe_vm_madvise_ioctl(struct drm_device *dev, void *data,
> struct drm_file *fil
> > drm_exec_fini(&exec);
> > free_vmas:
> > kfree(madvise_range.vmas);
> > - madvise_range.vmas = NULL;
>
> Do we really need this change?
I think it is suggested by me. Since there is Fixes tag for this patch, to avoid backport conflict and restrict change ONLY to the fix, I prefer we don't do this change also.
Shuicheng
>
> Otherwise,
> Reviewed-by: Matthew Auld <matthew.auld@intel.com>
>
> > madv_fini:
> > xe_madvise_details_fini(&details);
> > unlock_vm:
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v5 0/2] drm/xe: PAT index validation for CPU_ADDR_MIRROR and madvise
[not found] <20260129000147.339361-1-jia.yao@intel.com>
` (2 preceding siblings ...)
2026-03-16 7:22 ` [PATCH v5 0/2] drm/xe: PAT index validation for CPU_ADDR_MIRROR and Jia Yao
@ 2026-03-16 16:42 ` Jia Yao
2026-03-16 16:42 ` [PATCH v6 1/2] drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise Jia Yao
2026-03-16 16:42 ` [PATCH v6 2/2] drm/xe: Reject coh_none PAT index for CPU_ADDR_MIRROR Jia Yao
2026-03-19 11:58 ` [PATCH v7 0/2] drm/xe: PAT index validation for CPU_ADDR_MIRROR and madvise Jia Yao
4 siblings, 2 replies; 20+ messages in thread
From: Jia Yao @ 2026-03-16 16:42 UTC (permalink / raw)
To: intel-xe
Cc: Jia Yao, stable, Shuicheng Lin, Mathew Alwin, Michal Mrozek,
Matthew Brost, Matthew Auld
This series strengthens PAT index validation to reject unsafe
configurations for CPU cached memory, preventing cases where the GPU may
bypass CPU caches and observe stale or sensitive data.
Patch 1 enforces PAT validation for the madvise ioctl path, ensuring
XE_COH_NONE cannot be used on CPU cached buffers, including CPU address
mirror and userptr-backed memory.
Patch 2 applies the same validation to vm_bind, treating
DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR the same as MAP_USERPTR with
respect to permissible PAT indices.
Both patches close a security gap affecting CPU cached memory access
when incoherent PAT values are used.
Changes since v5:
- Added an additional Fixes tag to correctly reference the root cause
patch enabling the problematic PAT behavior.
Fixes: ada7486c5668 ("drm/xe: Implement madvise ioctl for xe")
Fixes: e1fbc4f18d5b ("drm/xe/uapi: support pat_index selection with vm_bind")
Cc: stable@vger.kernel.org # v6.18
Cc: Shuicheng Lin <shuicheng.lin@intel.com>
Cc: Mathew Alwin <alwin.mathew@intel.com>
Cc: Michal Mrozek <michal.mrozek@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
Jia Yao (2):
drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in
madvise
drm/xe: Reject coh_none PAT index for CPU_ADDR_MIRROR
drivers/gpu/drm/xe/xe_vm.c | 2 +-
drivers/gpu/drm/xe/xe_vm_madvise.c | 45 ++++++++++++++++++++++++++++++
2 files changed, 46 insertions(+), 1 deletion(-)
--
2.43.0
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v6 1/2] drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise
2026-03-16 16:42 ` [PATCH v5 0/2] drm/xe: PAT index validation for CPU_ADDR_MIRROR and madvise Jia Yao
@ 2026-03-16 16:42 ` Jia Yao
2026-03-16 16:42 ` [PATCH v6 2/2] drm/xe: Reject coh_none PAT index for CPU_ADDR_MIRROR Jia Yao
1 sibling, 0 replies; 20+ messages in thread
From: Jia Yao @ 2026-03-16 16:42 UTC (permalink / raw)
To: intel-xe
Cc: Jia Yao, stable, Shuicheng Lin, Mathew Alwin, Michal Mrozek,
Matthew Brost, Matthew Auld, José Roberto de Souza
Add validation in xe_vm_madvise_ioctl() to reject PAT indices with
XE_COH_NONE coherency mode when applied to CPU cached memory.
Using coh_none with CPU cached buffers is a security issue. When the
kernel clears pages before reallocation, the clear operation stays in
CPU cache (dirty). GPU with coh_none can bypass CPU caches and read
stale sensitive data directly from DRAM, potentially leaking data from
previously freed pages of other processes.
This aligns with the existing validation in vm_bind path
(xe_vm_bind_ioctl_validate_bo).
v2(Matthew brost)
- Add fixes
- Move one debug print to better place
v3(Matthew Auld)
- Should be drm/xe/uapi
- More Cc
v4(Shuicheng Lin)
- Fix kmem leak issues by the way
v5
- Remove kmem leak because it has been merged by another patch
v6
- Remove the fix which is not related to current fix
Fixes: ada7486c5668 ("drm/xe: Implement madvise ioctl for xe")
Cc: stable@vger.kernel.org # v6.18
Cc: Shuicheng Lin <shuicheng.lin@intel.com>
Cc: Mathew Alwin <alwin.mathew@intel.com>
Cc: Michal Mrozek <michal.mrozek@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Jia Yao <jia.yao@intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Acked-by: Michal Mrozek <michal.mrozek@intel.com>
Acked-by: José Roberto de Souza <jose.souza@intel.com>
---
drivers/gpu/drm/xe/xe_vm_madvise.c | 45 ++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/drivers/gpu/drm/xe/xe_vm_madvise.c b/drivers/gpu/drm/xe/xe_vm_madvise.c
index 869db304d96d..f26eb86e9c47 100644
--- a/drivers/gpu/drm/xe/xe_vm_madvise.c
+++ b/drivers/gpu/drm/xe/xe_vm_madvise.c
@@ -365,6 +365,43 @@ static void xe_madvise_details_fini(struct xe_madvise_details *details)
drm_pagemap_put(details->dpagemap);
}
+static bool check_pat_args_are_sane(struct xe_device *xe,
+ struct xe_vmas_in_madvise_range *madvise_range,
+ u16 pat_index)
+{
+ u16 coh_mode = xe_pat_index_get_coh_mode(xe, pat_index);
+ int i;
+
+ /*
+ * Using coh_none with CPU cached buffers is not allowed.
+ * Otherwise CPU page clearing can be bypassed, which is a
+ * security issue. GPU can directly access system memory and
+ * bypass CPU caches, potentially reading stale sensitive data
+ * from previously freed pages.
+ */
+ if (coh_mode != XE_COH_NONE)
+ return true;
+
+ for (i = 0; i < madvise_range->num_vmas; i++) {
+ struct xe_vma *vma = madvise_range->vmas[i];
+ struct xe_bo *bo = xe_vma_bo(vma);
+
+ if (bo) {
+ /* BO with WB caching + COH_NONE is not allowed */
+ if (XE_IOCTL_DBG(xe, bo->cpu_caching == DRM_XE_GEM_CPU_CACHING_WB))
+ return false;
+ /* Imported dma-buf without caching info, assume cached */
+ if (XE_IOCTL_DBG(xe, !bo->cpu_caching))
+ return false;
+ } else if (XE_IOCTL_DBG(xe, xe_vma_is_cpu_addr_mirror(vma) ||
+ xe_vma_is_userptr(vma)))
+ /* System memory (userptr/SVM) is always CPU cached */
+ return false;
+ }
+
+ return true;
+}
+
static bool check_bo_args_are_sane(struct xe_vm *vm, struct xe_vma **vmas,
int num_vmas, u32 atomic_val)
{
@@ -455,6 +492,14 @@ int xe_vm_madvise_ioctl(struct drm_device *dev, void *data, struct drm_file *fil
if (err || !madvise_range.num_vmas)
goto madv_fini;
+ if (args->type == DRM_XE_MEM_RANGE_ATTR_PAT) {
+ if (!check_pat_args_are_sane(xe, &madvise_range,
+ args->pat_index.val)) {
+ err = -EINVAL;
+ goto free_vmas;
+ }
+ }
+
if (madvise_range.has_bo_vmas) {
if (args->type == DRM_XE_MEM_RANGE_ATTR_ATOMIC) {
if (!check_bo_args_are_sane(vm, madvise_range.vmas,
--
2.43.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v6 2/2] drm/xe: Reject coh_none PAT index for CPU_ADDR_MIRROR
2026-03-16 16:42 ` [PATCH v5 0/2] drm/xe: PAT index validation for CPU_ADDR_MIRROR and madvise Jia Yao
2026-03-16 16:42 ` [PATCH v6 1/2] drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise Jia Yao
@ 2026-03-16 16:42 ` Jia Yao
2026-03-17 10:45 ` Matthew Auld
1 sibling, 1 reply; 20+ messages in thread
From: Jia Yao @ 2026-03-16 16:42 UTC (permalink / raw)
To: intel-xe
Cc: Jia Yao, stable, Shuicheng Lin, Mathew Alwin, Michal Mrozek,
Matthew Brost, Matthew Auld
Add validation in xe_vm_bind_ioctl() to reject PAT indices with
XE_COH_NONE coherency mode when used with
DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR, consistent with the existing
validation for DRM_XE_VM_BIND_OP_MAP_USERPTR.
CPU address mirror mappings use system memory which is CPU cached,
making them incompatible with COH_NONE PAT index. Using COH_NONE with
CPU cached buffers is a security issue: GPU can bypass CPU caches and
directly read stale sensitive data from DRAM, potentially leaking data
from previously freed pages.
Although CPU_ADDR_MIRROR mappings don't create actual memory mappings
(the range is reserved for dynamic mapping on GPU page faults), the
underlying system memory is still CPU cached, so the same PAT coherency
restrictions as MAP_USERPTR should apply.
v2:
- Correct fix tag
Fixes: e1fbc4f18d5b ("drm/xe/uapi: support pat_index selection with vm_bind")
Cc: stable@vger.kernel.org # v6.18
Cc: Shuicheng Lin <shuicheng.lin@intel.com>
Cc: Mathew Alwin <alwin.mathew@intel.com>
Cc: Michal Mrozek <michal.mrozek@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Jia Yao <jia.yao@intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
---
drivers/gpu/drm/xe/xe_vm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index 5572e12c2a7e..1c4b4a5eeadb 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -3491,7 +3491,7 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe, struct xe_vm *vm,
XE_IOCTL_DBG(xe, obj &&
op == DRM_XE_VM_BIND_OP_MAP_USERPTR) ||
XE_IOCTL_DBG(xe, coh_mode == XE_COH_NONE &&
- op == DRM_XE_VM_BIND_OP_MAP_USERPTR) ||
+ (op == DRM_XE_VM_BIND_OP_MAP_USERPTR || is_cpu_addr_mirror)) ||
XE_IOCTL_DBG(xe, comp_en &&
op == DRM_XE_VM_BIND_OP_MAP_USERPTR) ||
XE_IOCTL_DBG(xe, op == DRM_XE_VM_BIND_OP_MAP_USERPTR &&
--
2.43.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v6 2/2] drm/xe: Reject coh_none PAT index for CPU_ADDR_MIRROR
2026-03-16 16:42 ` [PATCH v6 2/2] drm/xe: Reject coh_none PAT index for CPU_ADDR_MIRROR Jia Yao
@ 2026-03-17 10:45 ` Matthew Auld
0 siblings, 0 replies; 20+ messages in thread
From: Matthew Auld @ 2026-03-17 10:45 UTC (permalink / raw)
To: Jia Yao, intel-xe
Cc: stable, Shuicheng Lin, Mathew Alwin, Michal Mrozek, Matthew Brost
On 16/03/2026 16:42, Jia Yao wrote:
> Add validation in xe_vm_bind_ioctl() to reject PAT indices with
> XE_COH_NONE coherency mode when used with
> DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR, consistent with the existing
> validation for DRM_XE_VM_BIND_OP_MAP_USERPTR.
>
> CPU address mirror mappings use system memory which is CPU cached,
> making them incompatible with COH_NONE PAT index. Using COH_NONE with
> CPU cached buffers is a security issue: GPU can bypass CPU caches and
> directly read stale sensitive data from DRAM, potentially leaking data
> from previously freed pages.
>
> Although CPU_ADDR_MIRROR mappings don't create actual memory mappings
> (the range is reserved for dynamic mapping on GPU page faults), the
> underlying system memory is still CPU cached, so the same PAT coherency
> restrictions as MAP_USERPTR should apply.
>
> v2:
> - Correct fix tag
>
> Fixes: e1fbc4f18d5b ("drm/xe/uapi: support pat_index selection with vm_bind")
I don't think addr_mirror existed yet?
Maybe:
Fixes: b43e864af0d4 ("drm/xe/uapi: Add DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR")
Cc: <stable@vger.kernel.org> # v6.15+
> Cc: stable@vger.kernel.org # v6.18
> Cc: Shuicheng Lin <shuicheng.lin@intel.com>
> Cc: Mathew Alwin <alwin.mathew@intel.com>
> Cc: Michal Mrozek <michal.mrozek@intel.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
> Cc: Matthew Auld <matthew.auld@intel.com>
> Signed-off-by: Jia Yao <jia.yao@intel.com>
> Reviewed-by: Matthew Auld <matthew.auld@intel.com>
> ---
> drivers/gpu/drm/xe/xe_vm.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
> index 5572e12c2a7e..1c4b4a5eeadb 100644
> --- a/drivers/gpu/drm/xe/xe_vm.c
> +++ b/drivers/gpu/drm/xe/xe_vm.c
> @@ -3491,7 +3491,7 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe, struct xe_vm *vm,
> XE_IOCTL_DBG(xe, obj &&
> op == DRM_XE_VM_BIND_OP_MAP_USERPTR) ||
> XE_IOCTL_DBG(xe, coh_mode == XE_COH_NONE &&
> - op == DRM_XE_VM_BIND_OP_MAP_USERPTR) ||
> + (op == DRM_XE_VM_BIND_OP_MAP_USERPTR || is_cpu_addr_mirror)) ||
> XE_IOCTL_DBG(xe, comp_en &&
> op == DRM_XE_VM_BIND_OP_MAP_USERPTR) ||
> XE_IOCTL_DBG(xe, op == DRM_XE_VM_BIND_OP_MAP_USERPTR &&
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v7 0/2] drm/xe: PAT index validation for CPU_ADDR_MIRROR and madvise
[not found] <20260129000147.339361-1-jia.yao@intel.com>
` (3 preceding siblings ...)
2026-03-16 16:42 ` [PATCH v5 0/2] drm/xe: PAT index validation for CPU_ADDR_MIRROR and madvise Jia Yao
@ 2026-03-19 11:58 ` Jia Yao
2026-03-19 11:58 ` [PATCH v7 1/2] drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise Jia Yao
2026-03-19 11:58 ` [PATCH v7 2/2] drm/xe: Reject coh_none PAT index for CPU_ADDR_MIRROR Jia Yao
4 siblings, 2 replies; 20+ messages in thread
From: Jia Yao @ 2026-03-19 11:58 UTC (permalink / raw)
To: intel-xe
Cc: Jia Yao, stable, Shuicheng Lin, Mathew Alwin, Michal Mrozek,
Matthew Brost, Matthew Auld
This series strengthens PAT index validation to reject unsafe
configurations for CPU cached memory, preventing cases where the GPU may
bypass CPU caches and observe stale or sensitive data.
Patch 1 enforces PAT validation for the madvise ioctl path, ensuring
XE_COH_NONE cannot be used on CPU cached buffers, including CPU address
mirror and userptr-backed memory.
Patch 2 applies the same validation to vm_bind, treating
DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR the same as MAP_USERPTR with
respect to permissible PAT indices.
Both patches close a security gap affecting CPU cached memory access
when incoherent PAT values are used.
Changes since v6:
- Correct fixes tag
Fixes: b43e864af0d4 ("drm/xe/uapi: Add DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR")
Fixes: e1fbc4f18d5b ("drm/xe/uapi: support pat_index selection with vm_bind")
Cc: stable@vger.kernel.org # v6.18
Cc: Shuicheng Lin <shuicheng.lin@intel.com>
Cc: Mathew Alwin <alwin.mathew@intel.com>
Cc: Michal Mrozek <michal.mrozek@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
Jia Yao (2):
drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in
madvise
drm/xe: Reject coh_none PAT index for CPU_ADDR_MIRROR
drivers/gpu/drm/xe/xe_vm.c | 2 +-
drivers/gpu/drm/xe/xe_vm_madvise.c | 45 ++++++++++++++++++++++++++++++
2 files changed, 46 insertions(+), 1 deletion(-)
--
2.43.0
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v7 1/2] drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise
2026-03-19 11:58 ` [PATCH v7 0/2] drm/xe: PAT index validation for CPU_ADDR_MIRROR and madvise Jia Yao
@ 2026-03-19 11:58 ` Jia Yao
2026-03-19 11:58 ` [PATCH v7 2/2] drm/xe: Reject coh_none PAT index for CPU_ADDR_MIRROR Jia Yao
1 sibling, 0 replies; 20+ messages in thread
From: Jia Yao @ 2026-03-19 11:58 UTC (permalink / raw)
To: intel-xe
Cc: Jia Yao, stable, Shuicheng Lin, Mathew Alwin, Michal Mrozek,
Matthew Brost, Matthew Auld, José Roberto de Souza
Add validation in xe_vm_madvise_ioctl() to reject PAT indices with
XE_COH_NONE coherency mode when applied to CPU cached memory.
Using coh_none with CPU cached buffers is a security issue. When the
kernel clears pages before reallocation, the clear operation stays in
CPU cache (dirty). GPU with coh_none can bypass CPU caches and read
stale sensitive data directly from DRAM, potentially leaking data from
previously freed pages of other processes.
This aligns with the existing validation in vm_bind path
(xe_vm_bind_ioctl_validate_bo).
v2(Matthew brost)
- Add fixes
- Move one debug print to better place
v3(Matthew Auld)
- Should be drm/xe/uapi
- More Cc
v4(Shuicheng Lin)
- Fix kmem leak issues by the way
v5
- Remove kmem leak because it has been merged by another patch
v6
- Remove the fix which is not related to current fix
v7
- No change
Fixes: ada7486c5668 ("drm/xe: Implement madvise ioctl for xe")
Cc: stable@vger.kernel.org # v6.18
Cc: Shuicheng Lin <shuicheng.lin@intel.com>
Cc: Mathew Alwin <alwin.mathew@intel.com>
Cc: Michal Mrozek <michal.mrozek@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Jia Yao <jia.yao@intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Acked-by: Michal Mrozek <michal.mrozek@intel.com>
Acked-by: José Roberto de Souza <jose.souza@intel.com>
---
drivers/gpu/drm/xe/xe_vm_madvise.c | 45 ++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/drivers/gpu/drm/xe/xe_vm_madvise.c b/drivers/gpu/drm/xe/xe_vm_madvise.c
index 869db304d96d..f26eb86e9c47 100644
--- a/drivers/gpu/drm/xe/xe_vm_madvise.c
+++ b/drivers/gpu/drm/xe/xe_vm_madvise.c
@@ -365,6 +365,43 @@ static void xe_madvise_details_fini(struct xe_madvise_details *details)
drm_pagemap_put(details->dpagemap);
}
+static bool check_pat_args_are_sane(struct xe_device *xe,
+ struct xe_vmas_in_madvise_range *madvise_range,
+ u16 pat_index)
+{
+ u16 coh_mode = xe_pat_index_get_coh_mode(xe, pat_index);
+ int i;
+
+ /*
+ * Using coh_none with CPU cached buffers is not allowed.
+ * Otherwise CPU page clearing can be bypassed, which is a
+ * security issue. GPU can directly access system memory and
+ * bypass CPU caches, potentially reading stale sensitive data
+ * from previously freed pages.
+ */
+ if (coh_mode != XE_COH_NONE)
+ return true;
+
+ for (i = 0; i < madvise_range->num_vmas; i++) {
+ struct xe_vma *vma = madvise_range->vmas[i];
+ struct xe_bo *bo = xe_vma_bo(vma);
+
+ if (bo) {
+ /* BO with WB caching + COH_NONE is not allowed */
+ if (XE_IOCTL_DBG(xe, bo->cpu_caching == DRM_XE_GEM_CPU_CACHING_WB))
+ return false;
+ /* Imported dma-buf without caching info, assume cached */
+ if (XE_IOCTL_DBG(xe, !bo->cpu_caching))
+ return false;
+ } else if (XE_IOCTL_DBG(xe, xe_vma_is_cpu_addr_mirror(vma) ||
+ xe_vma_is_userptr(vma)))
+ /* System memory (userptr/SVM) is always CPU cached */
+ return false;
+ }
+
+ return true;
+}
+
static bool check_bo_args_are_sane(struct xe_vm *vm, struct xe_vma **vmas,
int num_vmas, u32 atomic_val)
{
@@ -455,6 +492,14 @@ int xe_vm_madvise_ioctl(struct drm_device *dev, void *data, struct drm_file *fil
if (err || !madvise_range.num_vmas)
goto madv_fini;
+ if (args->type == DRM_XE_MEM_RANGE_ATTR_PAT) {
+ if (!check_pat_args_are_sane(xe, &madvise_range,
+ args->pat_index.val)) {
+ err = -EINVAL;
+ goto free_vmas;
+ }
+ }
+
if (madvise_range.has_bo_vmas) {
if (args->type == DRM_XE_MEM_RANGE_ATTR_ATOMIC) {
if (!check_bo_args_are_sane(vm, madvise_range.vmas,
--
2.43.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v7 2/2] drm/xe: Reject coh_none PAT index for CPU_ADDR_MIRROR
2026-03-19 11:58 ` [PATCH v7 0/2] drm/xe: PAT index validation for CPU_ADDR_MIRROR and madvise Jia Yao
2026-03-19 11:58 ` [PATCH v7 1/2] drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise Jia Yao
@ 2026-03-19 11:58 ` Jia Yao
1 sibling, 0 replies; 20+ messages in thread
From: Jia Yao @ 2026-03-19 11:58 UTC (permalink / raw)
To: intel-xe
Cc: Jia Yao, stable, Shuicheng Lin, Mathew Alwin, Michal Mrozek,
Matthew Brost, Matthew Auld
Add validation in xe_vm_bind_ioctl() to reject PAT indices with
XE_COH_NONE coherency mode when used with
DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR, consistent with the existing
validation for DRM_XE_VM_BIND_OP_MAP_USERPTR.
CPU address mirror mappings use system memory which is CPU cached,
making them incompatible with COH_NONE PAT index. Using COH_NONE with
CPU cached buffers is a security issue: GPU can bypass CPU caches and
directly read stale sensitive data from DRAM, potentially leaking data
from previously freed pages.
Although CPU_ADDR_MIRROR mappings don't create actual memory mappings
(the range is reserved for dynamic mapping on GPU page faults), the
underlying system memory is still CPU cached, so the same PAT coherency
restrictions as MAP_USERPTR should apply.
v2:
- Correct fix tag
v6:
- No change
v7:
- Correct fix tag
Fixes: b43e864af0d4 ("drm/xe/uapi: Add DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR")
Cc: stable@vger.kernel.org # v6.18
Cc: Shuicheng Lin <shuicheng.lin@intel.com>
Cc: Mathew Alwin <alwin.mathew@intel.com>
Cc: Michal Mrozek <michal.mrozek@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Jia Yao <jia.yao@intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
---
drivers/gpu/drm/xe/xe_vm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index 5572e12c2a7e..1c4b4a5eeadb 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -3491,7 +3491,7 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe, struct xe_vm *vm,
XE_IOCTL_DBG(xe, obj &&
op == DRM_XE_VM_BIND_OP_MAP_USERPTR) ||
XE_IOCTL_DBG(xe, coh_mode == XE_COH_NONE &&
- op == DRM_XE_VM_BIND_OP_MAP_USERPTR) ||
+ (op == DRM_XE_VM_BIND_OP_MAP_USERPTR || is_cpu_addr_mirror)) ||
XE_IOCTL_DBG(xe, comp_en &&
op == DRM_XE_VM_BIND_OP_MAP_USERPTR) ||
XE_IOCTL_DBG(xe, op == DRM_XE_VM_BIND_OP_MAP_USERPTR &&
--
2.43.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
end of thread, other threads:[~2026-03-19 11:59 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20260129000147.339361-1-jia.yao@intel.com>
2026-01-30 22:07 ` [PATCH v3] drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise Jia Yao
2026-02-03 2:54 ` Lin, Shuicheng
2026-02-04 15:13 ` Souza, Jose
2026-02-03 15:48 ` [PATCH v4] " Jia Yao
2026-02-03 16:38 ` Matthew Auld
2026-02-03 16:59 ` Yao, Jia
2026-03-10 14:50 ` Mrozek, Michal
2026-03-16 7:22 ` [PATCH v5 0/2] drm/xe: PAT index validation for CPU_ADDR_MIRROR and Jia Yao
2026-03-16 7:22 ` [PATCH v5 1/2] drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise Jia Yao
2026-03-16 10:59 ` Matthew Auld
2026-03-16 15:29 ` Lin, Shuicheng
2026-03-16 7:22 ` [PATCH v5 2/2] drm/xe: Reject coh_none PAT index for CPU_ADDR_MIRROR Jia Yao
2026-03-16 11:40 ` Matthew Auld
2026-03-16 16:42 ` [PATCH v5 0/2] drm/xe: PAT index validation for CPU_ADDR_MIRROR and madvise Jia Yao
2026-03-16 16:42 ` [PATCH v6 1/2] drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise Jia Yao
2026-03-16 16:42 ` [PATCH v6 2/2] drm/xe: Reject coh_none PAT index for CPU_ADDR_MIRROR Jia Yao
2026-03-17 10:45 ` Matthew Auld
2026-03-19 11:58 ` [PATCH v7 0/2] drm/xe: PAT index validation for CPU_ADDR_MIRROR and madvise Jia Yao
2026-03-19 11:58 ` [PATCH v7 1/2] drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise Jia Yao
2026-03-19 11:58 ` [PATCH v7 2/2] drm/xe: Reject coh_none PAT index for CPU_ADDR_MIRROR Jia Yao
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox