Preferring pointers to vm_offset_t
John Baldwin <[email protected]> Tue, 10 Mar 2026 15:22:01 -0400
| Newsgroups | gmane.os.freebsd.architechture |
|---|---|
| Message-ID | <[email protected]> |
On CHERI architectures, pointers (and uintptr_t) are not the same size as addresses. CHERI introduces a new ptraddr_t type (that is basically an alias of size_t) to represent a scalar integer type that can hold addresses. Various places in FreeBSD have conflated pointers and addresses. For example, rtld and the kernel linker often treat Elf_Addr as if it can hold a uintptr_t which is not true on CHERI. Another example is vm_offset_t in the VM system and related APIs. When porting FreeBSD to CHERI, we have usually taken the approach of migrating to uintptr_t for these cases (e.g. see recent changes from Jessica that converted much of the TLS handling in rtld to use uintptr_t instead of Elf_Addr). For the kernel, CheriBSD currently adds a new vm_pointer_t type that is an alias of uintptr_t and leaves vm_offset_t as a type that only describes addresses. However, this approach can have some downsides. Notably, C allows silent promotion/demotion of integer types, and in turn this means that assiging a uintptr_t to a ptraddr_t (or vice versa) compiles fine without any warnings. This does mean that if you accidentally round trip a pointer via a ptraddr_t (e.g. using vm_offset_t instead of vm_pointer_t in the kernel), you silently strip the metadata and validity from the pointer making it unusable. At the same time, many of our current in-kernel APIs that operate on kernel pointers (i.e. the calling code intends to dereference these pointers directly) use vm_offset_t and require casts. To that end, the approach we believe we want to take for upstreaming CHERI to the kernel is to adjust APIs that work with kernel pointers to use pointer types such as void * (or occasionally char * if pointer arithmetic is commonly used on the value or struct member) instead of vm_offset_t. In practice this seems to remove the need for casts in lots of places, and it enforces compile-time type checking both for CHERI and non-CHERI architectures (so that amd64 builds also break if you get this wrong, not just compiles on CHERI architectures). I've already upstreamed a few changes in this vein: e48770de6831 arm64: Use void pointers for arguments to arm64_get_writable_addr 1e3f42b6bad5 arm64: Switch the address argument to cpu_*cache* to a pointer eab7ae7811f6 arm64 gicv3: Use void pointers instead of vm_offset_t 7ae99f80b666 pmap_unmapdev/bios: Accept a pointer instead of a vm_offset_t. I have a larger batch of these changes queued up in a branch for review. Due to the size of the branch, I've posted it on GH as phab really doesn't scale well for large branches: https://github.com/freebsd/freebsd-src/pull/2068 This affects APIs such as PHYS_TO_DMAP, kva_*, pmap_quick_*, pmap_map, pmap_qenter, td_kstack, and some others. -- John Baldwin