diff options
| author | Konstantin Belousov <kib@FreeBSD.org> | 2025-03-29 17:17:01 +0000 |
|---|---|---|
| committer | Konstantin Belousov <kib@FreeBSD.org> | 2026-05-28 12:38:25 +0000 |
| commit | 7b2702ee25f5230011fa7f8f650b65b37248fcca (patch) | |
| tree | 2cb7e96ceb58e0c2f397cb8d62c7628a7dafa561 | |
| parent | 67d61d18bb8debb4ffc51ef2248aa37ed0bfb8f5 (diff) | |
sys: add safe_read(9)
The MD function with MI interface to provide a way to read arbitrary
(canonical) KVA. amd64 only for now.
Reviewed by: markj
Tested by: aokblast
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D49566
| -rw-r--r-- | sys/amd64/amd64/machdep.c | 18 | ||||
| -rw-r--r-- | sys/sys/systm.h | 8 |
2 files changed, 26 insertions, 0 deletions
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index dbad85096a1d..db2fd5927f7f 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -1852,6 +1852,24 @@ wrmsr_early_safe_end(void) memset_early(gpf_descr, 0, sizeof(*gpf_descr)); } +int +safe_read(vm_offset_t addr, char *valp) +{ + struct uio uio; + struct iovec iov; + + iov.iov_base = valp; + iov.iov_len = 1; + uio.uio_offset = addr; + uio.uio_iov = &iov; + uio.uio_iovcnt = 1; + uio.uio_resid = 1; + uio.uio_segflg = UIO_SYSSPACE; + uio.uio_rw = UIO_READ; + uio.uio_td = NULL; + return (uiomove_mem(UIO_MEM_KMEM, &uio)); +} + #ifdef KDB /* diff --git a/sys/sys/systm.h b/sys/sys/systm.h index 7f655b48ba08..88c25f06e0cb 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -554,6 +554,14 @@ void intr_prof_stack_use(struct thread *td, struct trapframe *frame); void counted_warning(unsigned *counter, const char *msg); /* + * Safely read one byte of kernel memory at address addr, placing the + * value into *valp. Returns 0 on success, EFAULT if read was + * impossible, e.g. due to the address not being mapped or not having + * necessary permissions. + */ +int safe_read(vm_offset_t addr, char *valp); + +/* * APIs to manage deprecation and obsolescence. */ void _gone_in(int major, const char *msg, ...) __printflike(2, 3); |
