The branch main has been updated by markj:

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

commit a7e483ee146a93ac89357676fdb9af62ac58b4bc
Author:     Mark Johnston <[email protected]>
AuthorDate: 2026-07-19 00:29:40 +0000
Commit:     Mark Johnston <[email protected]>
CommitDate: 2026-07-19 00:29:40 +0000

    vm_phys: Add a sysctl to dump registered fictitious memory ranges
    
    I've wanted this a couple of times in the past.  Save the memattr in
    the fictitious memory segment structure so that we can report it from
    the sysctl handler, and add conversion routines for each platform.
    
    Reviewed by:    kib
    MFC after:      2 weeks
    Differential Revision:  https://reviews.freebsd.org/D58283
---
 sys/amd64/include/vm.h   | 23 +++++++++++++++++++++++
 sys/arm/include/vm.h     | 19 +++++++++++++++++++
 sys/arm64/include/vm.h   | 25 +++++++++++++++++++++++--
 sys/i386/include/vm.h    | 23 +++++++++++++++++++++++
 sys/powerpc/include/vm.h | 25 +++++++++++++++++++++++++
 sys/riscv/include/vm.h   | 17 +++++++++++++++++
 sys/vm/vm_phys.c         | 41 +++++++++++++++++++++++++++++++++++++++++
 7 files changed, 171 insertions(+), 2 deletions(-)

diff --git a/sys/amd64/include/vm.h b/sys/amd64/include/vm.h
index 2e156b1cb1be..7219f8650a9f 100644
--- a/sys/amd64/include/vm.h
+++ b/sys/amd64/include/vm.h
@@ -43,4 +43,27 @@
 #define        VM_MEMATTR_DEFAULT              VM_MEMATTR_WRITE_BACK
 #define        VM_MEMATTR_DEVICE               VM_MEMATTR_UNCACHEABLE
 
+#ifdef _KERNEL
+static inline const char *
+vm_memattr_name(vm_memattr_t memattr)
+{
+       switch (memattr) {
+       case VM_MEMATTR_UNCACHEABLE:
+               return ("uncacheable");
+       case VM_MEMATTR_WRITE_COMBINING:
+               return ("write-combining");
+       case VM_MEMATTR_WRITE_THROUGH:
+               return ("write-through");
+       case VM_MEMATTR_WRITE_PROTECTED:
+               return ("write-protected");
+       case VM_MEMATTR_WRITE_BACK:
+               return ("write-back");
+       case VM_MEMATTR_WEAK_UNCACHEABLE:
+               return ("weak-uncacheable");
+       default:
+               return (NULL);
+       }
+}
+#endif
+
 #endif /* !_MACHINE_VM_H_ */
diff --git a/sys/arm/include/vm.h b/sys/arm/include/vm.h
index 697b48689bd8..373f51adec82 100644
--- a/sys/arm/include/vm.h
+++ b/sys/arm/include/vm.h
@@ -41,6 +41,25 @@
 /* Don't export aliased VM_MEMATTR to userland */
 #define VM_MEMATTR_WRITE_COMBINING     VM_MEMATTR_WRITE_THROUGH /* for DRM */
 #define VM_MEMATTR_WRITE_BACK          VM_MEMATTR_WB_WA        /* for DRM */
+
+static inline const char *
+vm_memattr_name(vm_memattr_t memattr)
+{
+       switch (memattr) {
+       case VM_MEMATTR_WB_WA:
+               return ("write-back, write-allocate");
+       case VM_MEMATTR_NOCACHE:
+               return ("uncacheable");
+       case VM_MEMATTR_DEVICE:
+               return ("device");
+       case VM_MEMATTR_SO:
+               return ("strongly-ordered");
+       case VM_MEMATTR_WRITE_THROUGH:
+               return ("write-through");
+       default:
+               return (NULL);
+       }
+}
 #endif
 
 #endif /* !_MACHINE_VM_H_ */
diff --git a/sys/arm64/include/vm.h b/sys/arm64/include/vm.h
index 4d9f2860f654..87a1839b7dac 100644
--- a/sys/arm64/include/vm.h
+++ b/sys/arm64/include/vm.h
@@ -39,11 +39,32 @@
 #define        VM_MEMATTR_DEVICE               VM_MEMATTR_DEVICE_nGnRE
 #define        VM_MEMATTR_DEVICE_NP            VM_MEMATTR_DEVICE_nGnRnE
 
+#define        VM_MEMATTR_DEFAULT              VM_MEMATTR_WRITE_BACK
+
 #ifdef _KERNEL
 /* If defined vmstat will try to use both of these in a switch statement */
 #define        VM_MEMATTR_WRITE_COMBINING      VM_MEMATTR_WRITE_THROUGH
-#endif
 
-#define        VM_MEMATTR_DEFAULT      VM_MEMATTR_WRITE_BACK
+static inline const char *
+vm_memattr_name(vm_memattr_t memattr)
+{
+       switch (memattr) {
+       case VM_MEMATTR_DEVICE_nGnRnE:
+               return ("device-nGnRnE");
+       case VM_MEMATTR_UNCACHEABLE:
+               return ("uncacheable");
+       case VM_MEMATTR_WRITE_BACK:
+               return ("write-back");
+       case VM_MEMATTR_WRITE_THROUGH:
+               return ("write-through");
+       case VM_MEMATTR_DEVICE_nGnRE:
+               return ("device-nGnRE");
+       case VM_MEMATTR_TAGGED:
+               return ("tagged");
+       default:
+               return (NULL);
+       }
+}
+#endif
 
 #endif /* !_MACHINE_VM_H_ */
diff --git a/sys/i386/include/vm.h b/sys/i386/include/vm.h
index 2e156b1cb1be..7219f8650a9f 100644
--- a/sys/i386/include/vm.h
+++ b/sys/i386/include/vm.h
@@ -43,4 +43,27 @@
 #define        VM_MEMATTR_DEFAULT              VM_MEMATTR_WRITE_BACK
 #define        VM_MEMATTR_DEVICE               VM_MEMATTR_UNCACHEABLE
 
+#ifdef _KERNEL
+static inline const char *
+vm_memattr_name(vm_memattr_t memattr)
+{
+       switch (memattr) {
+       case VM_MEMATTR_UNCACHEABLE:
+               return ("uncacheable");
+       case VM_MEMATTR_WRITE_COMBINING:
+               return ("write-combining");
+       case VM_MEMATTR_WRITE_THROUGH:
+               return ("write-through");
+       case VM_MEMATTR_WRITE_PROTECTED:
+               return ("write-protected");
+       case VM_MEMATTR_WRITE_BACK:
+               return ("write-back");
+       case VM_MEMATTR_WEAK_UNCACHEABLE:
+               return ("weak-uncacheable");
+       default:
+               return (NULL);
+       }
+}
+#endif
+
 #endif /* !_MACHINE_VM_H_ */
diff --git a/sys/powerpc/include/vm.h b/sys/powerpc/include/vm.h
index 5c99cda51257..87d0faf44f2e 100644
--- a/sys/powerpc/include/vm.h
+++ b/sys/powerpc/include/vm.h
@@ -42,4 +42,29 @@
 
 #define        VM_MEMATTR_DEVICE               VM_MEMATTR_DEFAULT
 
+#ifdef _KERNEL
+static inline const char *
+vm_memattr_name(vm_memattr_t memattr)
+{
+       switch (memattr) {
+       case VM_MEMATTR_DEFAULT:
+               return ("default");
+       case VM_MEMATTR_UNCACHEABLE:
+               return ("uncacheable");
+       case VM_MEMATTR_CACHEABLE:
+               return ("cacheable");
+       case VM_MEMATTR_WRITE_COMBINING:
+               return ("write-combining");
+       case VM_MEMATTR_WRITE_BACK:
+               return ("write-back");
+       case VM_MEMATTR_WRITE_THROUGH:
+               return ("write-through");
+       case VM_MEMATTR_PREFETCHABLE:
+               return ("prefetchable");
+       default:
+               return (NULL);
+       }
+}
+#endif
+
 #endif /* !_MACHINE_VM_H_ */
diff --git a/sys/riscv/include/vm.h b/sys/riscv/include/vm.h
index b6c0a7725124..66211fcc2580 100644
--- a/sys/riscv/include/vm.h
+++ b/sys/riscv/include/vm.h
@@ -38,4 +38,21 @@
 #define        VM_MEMATTR_LAST         VM_MEMATTR_DEVICE
 #define        VM_MEMATTR_TOTAL        (VM_MEMATTR_LAST + 1)
 
+#ifdef _KERNEL
+static inline const char *
+vm_memattr_name(vm_memattr_t memattr)
+{
+       switch (memattr) {
+       case VM_MEMATTR_PMA:
+               return ("write-back");
+       case VM_MEMATTR_UNCACHEABLE:
+               return ("uncacheable");
+       case VM_MEMATTR_DEVICE:
+               return ("device");
+       default:
+               return (NULL);
+       }
+}
+#endif
+
 #endif /* !_MACHINE_VM_H_ */
diff --git a/sys/vm/vm_phys.c b/sys/vm/vm_phys.c
index 1737020436c6..975754264fee 100644
--- a/sys/vm/vm_phys.c
+++ b/sys/vm/vm_phys.c
@@ -108,6 +108,7 @@ struct vm_phys_fictitious_seg {
        vm_paddr_t      start;
        vm_paddr_t      end;
        vm_page_t       first_page;
+       vm_memattr_t    memattr;
 };
 
 RB_GENERATE_STATIC(fict_tree, vm_phys_fictitious_seg, node,
@@ -172,6 +173,12 @@ SYSCTL_OID(_vm, OID_AUTO, phys_segs,
     sysctl_vm_phys_segs, "A",
     "Phys Seg Info");
 
+static int sysctl_vm_phys_fictitious_segs(SYSCTL_HANDLER_ARGS);
+SYSCTL_OID(_vm, OID_AUTO, phys_fictitious_segs,
+    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0,
+    sysctl_vm_phys_fictitious_segs, "A",
+    "Fictitious Phys Seg Info");
+
 #ifdef NUMA
 static int sysctl_vm_phys_locality(SYSCTL_HANDLER_ARGS);
 SYSCTL_OID(_vm, OID_AUTO, phys_locality,
@@ -341,6 +348,39 @@ sysctl_vm_phys_segs(SYSCTL_HANDLER_ARGS)
        return (error);
 }
 
+static int
+sysctl_vm_phys_fictitious_segs(SYSCTL_HANDLER_ARGS)
+{
+       struct sbuf sbuf;
+       struct vm_phys_fictitious_seg *seg;
+       int error;
+
+       error = sysctl_wire_old_buffer(req, 0);
+       if (error != 0)
+               return (error);
+       sbuf_new_for_sysctl(&sbuf, NULL, 128, req);
+       rw_rlock(&vm_phys_fictitious_reg_lock);
+       RB_FOREACH(seg, fict_tree, &vm_phys_fictitious_tree) {
+               const char *name;
+               char buf[8];
+
+               sbuf_printf(&sbuf, "\nstart:     %#jx\n",
+                   (uintmax_t)seg->start);
+               sbuf_printf(&sbuf, "end:       %#jx\n",
+                   (uintmax_t)seg->end);
+               name = vm_memattr_name(seg->memattr);
+               if (name == NULL) {
+                       (void)snprintf(buf, sizeof(buf), "0x%02x", 
seg->memattr);
+                       name = buf;
+               }
+               sbuf_printf(&sbuf, "attr:      %s\n", name);
+       }
+       rw_runlock(&vm_phys_fictitious_reg_lock);
+       error = sbuf_finish(&sbuf);
+       sbuf_delete(&sbuf);
+       return (error);
+}
+
 /*
  * Return affinity, or -1 if there's no affinity information.
  */
@@ -1155,6 +1195,7 @@ alloc:
        seg->start = start;
        seg->end = end;
        seg->first_page = fp;
+       seg->memattr = memattr;
 
        rw_wlock(&vm_phys_fictitious_reg_lock);
        RB_INSERT(fict_tree, &vm_phys_fictitious_tree, seg);

Reply via email to