On 10/20/25 17:00, Peter Maydell wrote:
I don't really understand this code, I'm just looking at
it fresh, so my comment below might be wrong.

-    /*
-     * If guest pages remain on the first or last host pages,
-     * adjust the deallocation to retain those guest pages.
-     * The single page special case is required for the last page,
-     * lest real_start overflow to zero.
-     */

This comment says we need the special case for
"real_last - real_start < host_page_size" to avoid an overflow.

-    if (real_last - real_start < host_page_size) {
-        prot = 0;

We delete the special case...

-        for (a = real_start; a < start; a += TARGET_PAGE_SIZE) {
-            prot |= page_get_flags(a);
-        }
-        for (a = last; a < real_last; a += TARGET_PAGE_SIZE) {
-            prot |= page_get_flags(a + 1);
-        }
-        if (prot != 0) {
-            return 0;
-        }
-    } else {
-        for (prot = 0, a = real_start; a < start; a += TARGET_PAGE_SIZE) {
-            prot |= page_get_flags(a);
-        }
-        if (prot != 0) {
-            real_start += host_page_size;
-        }
+    /* end or real_end may have overflowed to 0, but that's okay. */

-        for (prot = 0, a = last; a < real_last; a += TARGET_PAGE_SIZE) {
-            prot |= page_get_flags(a + 1);
-        }
-        if (prot != 0) {
-            real_last -= host_page_size;
-        }
+    /* If [real_start,start) contains a mapped guest page, retain the first 
page. */
+    for (prot = 0, off = 0; off < start - real_start; off += TARGET_PAGE_SIZE) 
{
+        prot |= page_get_flags(real_start + off);
+    }
+    if (prot != 0) {
+        real_start += host_page_size;

...and now if real_start was the last page in the
address space, this addition will overflow it to zero.
g
Indeed, but the idea (which I didn't make clear enough, apologies) is that this overflow is completely unproblematic. Provided you never perform inequality comparisons on the value, overflow gives correct results! Regardless though, Richard has asked that I revert to the old strategy:

On 10/21/2025, Richard Henderson wrote:
No, it is not simpler with 'end', because end == 0 is 'valid' in the sense that the range goes from [start, (abi_ptr)-1]. But having end
<= start is awkward in the extreme.

Thus we prefer the inclusive range [start, last] to the exclusive range [start, end).

Not everything has been converted away from 'end', but we certainly should not regress existing code.


r~
My perspective was that the only thing we actually lose from having 'end <= start' is the ability to perform comparisons on these addresses, and that this is better than the alternative, where we not only need the single-page special case, but also the corrected 'real_last' computation needs to use a temporarily-overflowed value:

  real_last = ROUND_UP(last + 1, host_page_size) - 1;

I'm not here to argue style, though, so I'm happy to replace this diff with a small one which only changes the 'real_last' definition. Will do that in the next version of this series.

--
Matthew

Reply via email to