From 6ada5978d023504e591bce2fd91d48ed7c262fd6 Mon Sep 17 00:00:00 2001 From: Vincent Franchomme Date: Thu, 16 Jan 2025 04:30:38 +0100 Subject: [PATCH] [NTOS:MM] Do not use PAGE_ROUND_DOWN for LONGLONG values (#7603) PAGE_ROUND_DOWN macro seems to not work correctly with LONGLONG values. It creates some random freezes in the 1st-stage setup after commit 69bf14050686f81db153c70df4f874b5dfa4a5ff. It's fixed by creating PAGE_ROUND_UP_64 and PAGE_ROUND_DOWN_64 macros for 64-bit only data types. --------- Co-authored-by: Thamatip Chitpong --- ntoskrnl/include/internal/mm.h | 7 +++++++ ntoskrnl/mm/section.c | 8 ++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/ntoskrnl/include/internal/mm.h b/ntoskrnl/include/internal/mm.h index 91bf7599df2..1c3870d6370 100644 --- a/ntoskrnl/include/internal/mm.h +++ b/ntoskrnl/include/internal/mm.h @@ -131,6 +131,13 @@ typedef ULONG_PTR SWAPENTRY; #define MM_ROUND_DOWN(x,s) \ ((PVOID)(((ULONG_PTR)(x)) & ~((ULONG_PTR)(s)-1))) +/* PAGE_ROUND_UP and PAGE_ROUND_DOWN equivalent, with support for 64-bit-only data types */ +#define PAGE_ROUND_UP_64(x) \ + (((x) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) + +#define PAGE_ROUND_DOWN_64(x) \ + ((x) & ~(PAGE_SIZE - 1)) + #define PAGE_FLAGS_VALID_FOR_SECTION \ (PAGE_READONLY | \ PAGE_READWRITE | \ diff --git a/ntoskrnl/mm/section.c b/ntoskrnl/mm/section.c index 73b414315fe..d570dbc3cec 100644 --- a/ntoskrnl/mm/section.c +++ b/ntoskrnl/mm/section.c @@ -4876,7 +4876,7 @@ MmPurgeSegment( } /* Find byte offset of the page to start */ - PurgeStart.QuadPart = PAGE_ROUND_DOWN(PurgeStart.QuadPart); + PurgeStart.QuadPart = PAGE_ROUND_DOWN_64(PurgeStart.QuadPart); while (PurgeStart.QuadPart < PurgeEnd.QuadPart) { @@ -4947,7 +4947,7 @@ MmIsDataSectionResident( return FALSE; /* Find byte offset of the page to start */ - RangeStart.QuadPart = PAGE_ROUND_DOWN(RangeStart.QuadPart); + RangeStart.QuadPart = PAGE_ROUND_DOWN_64(RangeStart.QuadPart); MmLockSectionSegment(Segment); @@ -5010,7 +5010,7 @@ MmMakeSegmentDirty( return STATUS_NOT_MAPPED_VIEW; /* Find byte offset of the page to start */ - RangeStart.QuadPart = PAGE_ROUND_DOWN(RangeStart.QuadPart); + RangeStart.QuadPart = PAGE_ROUND_DOWN_64(RangeStart.QuadPart); MmLockSectionSegment(Segment); @@ -5098,7 +5098,7 @@ MmFlushSegment( } /* Find byte offset of the page to start */ - FlushStart.QuadPart = PAGE_ROUND_DOWN(FlushStart.QuadPart); + FlushStart.QuadPart = PAGE_ROUND_DOWN_64(FlushStart.QuadPart); while (FlushStart.QuadPart < FlushEnd.QuadPart) {