aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2025-03-29 17:17:01 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2026-05-28 12:38:25 +0000
commit7b2702ee25f5230011fa7f8f650b65b37248fcca (patch)
tree2cb7e96ceb58e0c2f397cb8d62c7628a7dafa561
parent67d61d18bb8debb4ffc51ef2248aa37ed0bfb8f5 (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.c18
-rw-r--r--sys/sys/systm.h8
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);