vm_phys: Check for overlap when adding a segment

Segments are passed by machine-dependent routines, so explicit checks
will make debugging much easier on very weird machines or when someone
is tweaking these machine-dependent routines.  Additionally, this
operation is not performance-sensitive.

For the same reasons, test that we don't reach the maximum number of
physical segments (the compile-time of the internal storage) in
production kernels (replaces the existing KASSERT()).

Reviewed by:    markj
MFC after:      1 week
Sponsored by:   The FreeBSD Foundation
Differential Revision:  https://reviews.freebsd.org/D48628
This commit is contained in:
Olivier Certner 2024-10-10 09:41:40 +02:00
parent f30309abcc
commit 8a14ddcc1d
No known key found for this signature in database
GPG key ID: 8CA13040971E2627

View file

@ -421,18 +421,26 @@ _vm_phys_create_seg(vm_paddr_t start, vm_paddr_t end, int domain)
{
struct vm_phys_seg *seg;
KASSERT(vm_phys_nsegs < VM_PHYSSEG_MAX,
("vm_phys_create_seg: increase VM_PHYSSEG_MAX"));
KASSERT(domain >= 0 && domain < vm_ndomains,
("vm_phys_create_seg: invalid domain provided"));
if (!(0 <= domain && domain < vm_ndomains))
panic("%s: Invalid domain %d ('vm_ndomains' is %d)",
__func__, domain, vm_ndomains);
if (vm_phys_nsegs >= VM_PHYSSEG_MAX)
panic("Not enough storage for physical segments, "
"increase VM_PHYSSEG_MAX");
seg = &vm_phys_segs[vm_phys_nsegs++];
while (seg > vm_phys_segs && (seg - 1)->start >= end) {
while (seg > vm_phys_segs && seg[-1].start >= end) {
*seg = *(seg - 1);
seg--;
}
seg->start = start;
seg->end = end;
seg->domain = domain;
if (seg != vm_phys_segs && seg[-1].end > start)
panic("Overlapping physical segments: Current [%#jx,%#jx) "
"at index %zu, previous [%#jx,%#jx)",
(uintmax_t)start, (uintmax_t)end, seg - vm_phys_segs,
(uintmax_t)seg[-1].start, (uintmax_t)seg[-1].end);
}
static void