[PATCH OLK-6.6 0/2] fix amdgpu_hmm_range_get_pages
fix amdgpu_hmm_range_get_pages Christian König (1): drm/amdgpu: fix amdgpu_hmm_range_get_pages Honglei Huang (1): drm/amdgpu: drop retry loop in amdgpu_hmm_range_get_pages drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c | 30 +++++++------------------ 1 file changed, 8 insertions(+), 22 deletions(-) -- 2.34.1
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://atomgit.com/openeuler/kernel/merge_requests/25738 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/SR3... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://atomgit.com/openeuler/kernel/merge_requests/25738 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/SR3...
From: Christian König <christian.koenig@amd.com> mainline inclusion from mainline-v7.1-rc6 commit 962d684b5dc0741dcd93485d41b450de402d5592 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/16208 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- The notifier sequence must only be read once or otherwise we could work with invalid pages. While at it also fix the coding style, e.g. drop the pre-initialized return value and use the common define for 2G range. Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Vitaly Prosyak <vitaly.prosyak@amd.com> Tested-by: Vitaly Prosyak <vitaly.prosyak@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> (cherry picked from commit c08972f555945cda57b0adb72272a37910153390) Cc: stable@vger.kernel.org Conflicts: drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c [context conflicts.] Signed-off-by: Jiacheng Yu <yujiacheng3@huawei.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c index 57516a8c5db3..ebb0ee8813b3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c @@ -51,8 +51,6 @@ #include "amdgpu_amdkfd.h" #include "amdgpu_hmm.h" -#define MAX_WALK_BYTE (2UL << 30) - /** * amdgpu_hmm_invalidate_gfx - callback to notify about mm change * @@ -170,12 +168,14 @@ int amdgpu_hmm_range_get_pages(struct mmu_interval_notifier *notifier, void *owner, struct page **pages, struct hmm_range **phmm_range) { + const u64 max_bytes = SZ_2G; + struct hmm_range *hmm_range; - unsigned long end; unsigned long timeout; unsigned long i; unsigned long *pfns; - int r = 0; + unsigned long end; + int r; hmm_range = kzalloc(sizeof(*hmm_range), GFP_KERNEL); if (unlikely(!hmm_range)) @@ -196,8 +196,9 @@ int amdgpu_hmm_range_get_pages(struct mmu_interval_notifier *notifier, end = start + npages * PAGE_SIZE; hmm_range->dev_private_owner = owner; + hmm_range->notifier_seq = mmu_interval_read_begin(notifier); do { - hmm_range->end = min(hmm_range->start + MAX_WALK_BYTE, end); + hmm_range->end = min(hmm_range->start + max_bytes, end); pr_debug("hmm range: start = 0x%lx, end = 0x%lx", hmm_range->start, hmm_range->end); @@ -208,7 +209,6 @@ int amdgpu_hmm_range_get_pages(struct mmu_interval_notifier *notifier, timeout = jiffies + msecs_to_jiffies(timeout); retry: - hmm_range->notifier_seq = mmu_interval_read_begin(notifier); r = hmm_range_fault(hmm_range); if (unlikely(r)) { /* @@ -222,7 +222,7 @@ int amdgpu_hmm_range_get_pages(struct mmu_interval_notifier *notifier, if (hmm_range->end == end) break; - hmm_range->hmm_pfns += MAX_WALK_BYTE >> PAGE_SHIFT; + hmm_range->hmm_pfns += max_bytes >> PAGE_SHIFT; hmm_range->start = hmm_range->end; schedule(); } while (hmm_range->end < end); -- 2.34.1
From: Honglei Huang <honghuan@amd.com> mainline inclusion from mainline-v7.2-rc1 commit 342981fff32802a819d6fc7cf3c9fedf9f3d9d60 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/16208 CVE: CVE-2026-63879 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- Since commit c08972f55594 ("drm/amdgpu: fix amdgpu_hmm_range_get_pages") moved mmu_interval_read_begin() out of the per-chunk loop, the captured notifier_seq is no longer refreshed across retries. As a result, the existing -EBUSY retry path can never make progress: hmm_range_fault() returns -EBUSY only when mmu_interval_check_retry(notifier, notifier_seq) reports that the sequence is stale. Once the sequence has advanced, the stored seq will never match again, so every subsequent call within the same invocation returns -EBUSY immediately. The "goto retry" therefore degenerates into a busy spin that simply burns CPU for the full HMM_RANGE_DEFAULT_TIMEOUT (~1s) window before finally bailing out with -EAGAIN. This is pure latency with no chance of recovery, and it actively hurts the KFD userptr stack: the caller ends up blocked for a second while holding mmap_lock, only to return -EAGAIN to the restore worker (or to userspace) which would have re-driven the operation immediately anyway. Drop the retry/timeout entirely and let -EBUSY propagate straight to out_free_pfns, where it is already translated to -EAGAIN. Recovery is handled at a higher level: the KFD restore_userptr_worker reschedules itself, and the userptr ioctl path returns -EAGAIN to userspace. No functional regression: the previous behaviour on -EBUSY was already to fail with -EAGAIN after a 1s stall; we just skip the stall. Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Honglei Huang <honghuan@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Conflicts: drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c [context conflicts.] Signed-off-by: Jiacheng Yu <yujiacheng3@huawei.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c index ebb0ee8813b3..76b4a23c46d0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c @@ -171,7 +171,6 @@ int amdgpu_hmm_range_get_pages(struct mmu_interval_notifier *notifier, const u64 max_bytes = SZ_2G; struct hmm_range *hmm_range; - unsigned long timeout; unsigned long i; unsigned long *pfns; unsigned long end; @@ -203,22 +202,9 @@ int amdgpu_hmm_range_get_pages(struct mmu_interval_notifier *notifier, pr_debug("hmm range: start = 0x%lx, end = 0x%lx", hmm_range->start, hmm_range->end); - /* Assuming 128MB takes maximum 1 second to fault page address */ - timeout = max((hmm_range->end - hmm_range->start) >> 27, 1UL); - timeout *= HMM_RANGE_DEFAULT_TIMEOUT; - timeout = jiffies + msecs_to_jiffies(timeout); - -retry: r = hmm_range_fault(hmm_range); - if (unlikely(r)) { - /* - * FIXME: This timeout should encompass the retry from - * mmu_interval_read_retry() as well. - */ - if (r == -EBUSY && !time_after(jiffies, timeout)) - goto retry; + if (unlikely(r)) goto out_free_pfns; - } if (hmm_range->end == end) break; -- 2.34.1
participants (2)
-
Jiacheng Yu -
patchwork bot