git: 1e6d266d70e9 - stable/13 - kern: physmem: don't create a new exregion for different flags...

From: Kyle Evans <kevans_at_FreeBSD.org>
Date: Fri, 17 Mar 2023 05:48:41 UTC
The branch stable/13 has been updated by kevans:

URL: https://cgit.FreeBSD.org/src/commit/?id=1e6d266d70e969c87f5da229cc82b3d53ae7c2a5

commit 1e6d266d70e969c87f5da229cc82b3d53ae7c2a5
Author:     Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2023-03-10 05:27:39 +0000
Commit:     Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2023-03-17 05:04:22 +0000

    kern: physmem: don't create a new exregion for different flags...
    
    ... if the region we're adding is an exact match to one that we already
    have.  Simply extend the flags of the existing entry as needed so that
    we don't end up with duplicate regions.
    
    It could be that we got the exclusion through two different means, e.g.,
    FDT memreserve and the EFI memory map, and we may derive different
    characteristics from each.  Apply the most restrictive set to the
    region.
    
    Reported by:    Mark Millard <marklmi yahoo com>
    Reviewed by:    mhorne
    
    (cherry picked from commit cc0fe048ec39636216ed59fa47eb311b2537cfc5)
---
 sys/kern/subr_physmem.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/sys/kern/subr_physmem.c b/sys/kern/subr_physmem.c
index 7cb45621a155..450b891cb8a1 100644
--- a/sys/kern/subr_physmem.c
+++ b/sys/kern/subr_physmem.c
@@ -372,8 +372,8 @@ insert_region(struct region *regions, size_t rcnt, vm_paddr_t addr,
 	nend = addr + size;
 	ep = regions + rcnt;
 	for (i = 0, rp = regions; i < rcnt; ++i, ++rp) {
+		rend = rp->addr + rp->size;
 		if (flags == rp->flags) {
-			rend = rp->addr + rp->size;
 			if (addr <= rp->addr && nend >= rp->addr) {
 				/*
 				 * New mapping overlaps at the beginning, shift
@@ -400,7 +400,20 @@ insert_region(struct region *regions, size_t rcnt, vm_paddr_t addr,
 				}
 				return (rcnt);
 			}
+		} else if ((flags != 0) && (rp->flags != 0)) {
+			/*
+			 * If we're duplicating an entry that already exists
+			 * exactly, just upgrade its flags as needed.  We could
+			 * do more if we find that we have differently specified
+			 * flags clipping existing excluding regions, but that's
+			 * probably rare.
+			 */
+			if (addr == rp->addr && nend == rend) {
+				rp->flags |= flags;
+				return (rcnt);
+			}
 		}
+
 		if (addr < rp->addr) {
 			bcopy(rp, rp + 1, (ep - rp) * sizeof(*rp));
 			break;