Page MenuHomeFreeBSD

D26237.id76377.diff
No OneTemporary

D26237.id76377.diff

Index: share/man/man4/mem.4
===================================================================
--- share/man/man4/mem.4
+++ share/man/man4/mem.4
@@ -28,7 +28,7 @@
.\" @(#)mem.4 5.3 (Berkeley) 5/2/91
.\" $FreeBSD$
.\"
-.Dd October 3, 2004
+.Dd August 25, 2020
.Dt MEM 4
.Os
.Sh NAME
@@ -54,11 +54,7 @@
.Pa /dev/mem .
Only kernel virtual addresses that are currently mapped to memory are allowed.
.Pp
-On
-.Tn ISA
-the
-.Tn I/O
-memory space begins at physical address 0x000a0000
+On ISA the I/O memory space begins at physical address 0x000a0000
and runs to 0x00100000.
The
per-process data
@@ -69,6 +65,25 @@
long, and ends at virtual
address 0xf0000000.
.Sh IOCTL INTERFACE
+The
+.Dv MEM_EXTRACT_PADDR
+ioctl can be used to look up the physical address and NUMA domain of a given
+virtual address.
+The request is described by
+.Bd -literal
+struct mem_extract {
+ uint64_t me_vaddr; /* input */
+ uint64_t me_paddr; /* output */
+ int me_domain; /* output */
+};
+.Ed
+The ioctl fails with
+.Dv ENOENT
+if the address is not mapped at the time of the call.
+Note that a failure may occur even if the virtual address is valid, unless the
+range is wired, e.g., by
+.Xr mlock 2 .
+.Pp
Several architectures allow attributes to be associated with ranges of physical
memory.
These attributes can be manipulated via
@@ -95,12 +110,13 @@
.El
.Pp
Memory ranges are described by
-.Vt struct mem_range_desc :
-.Bd -literal -offset indent
-uint64_t mr_base; /\(** physical base address \(**/
-uint64_t mr_len; /\(** physical length of region \(**/
-int mr_flags; /\(** attributes of region \(**/
-char mr_owner[8];
+.Bd -literal
+struct mem_range_desc {
+ uint64_t mr_base; /* physical base address */
+ uint64_t mr_len; /* physical length of region */
+ int mr_flags; /* attributes of region */
+ char mr_owner[8];
+};
.Ed
.Pp
In addition to the region attributes listed above, the following flags
@@ -165,7 +181,7 @@
.It Bq Er EOPNOTSUPP
Memory range operations are not supported on this architecture.
.It Bq Er ENXIO
-No memory range descriptors are available (e.g.\& firmware has not enabled
+No memory range descriptors are available (e.g., firmware has not enabled
any).
.It Bq Er EINVAL
The memory range supplied as an argument is invalid or overlaps another
@@ -174,7 +190,7 @@
An attempt to remove or update a range failed because the range is busy.
.It Bq Er ENOSPC
An attempt to create a new range failed due to a shortage of hardware
-resources (e.g.\& descriptor slots).
+resources (e.g., descriptor slots).
.It Bq Er ENOENT
An attempt to remove a range failed because no range matches the descriptor
base/length supplied.
Index: sys/amd64/amd64/mem.c
===================================================================
--- sys/amd64/amd64/mem.c
+++ sys/amd64/amd64/mem.c
@@ -185,9 +185,8 @@
* This is basically just an ioctl shim for mem_range_attr_get
* and mem_range_attr_set.
*/
-/* ARGSUSED */
int
-memioctl(struct cdev *dev __unused, u_long cmd, caddr_t data, int flags,
+memioctl_md(struct cdev *dev __unused, u_long cmd, caddr_t data, int flags,
struct thread *td)
{
int nd, error = 0;
Index: sys/amd64/include/memdev.h
===================================================================
--- sys/amd64/include/memdev.h
+++ sys/amd64/include/memdev.h
@@ -36,7 +36,7 @@
d_open_t memopen;
d_read_t memrw;
-d_ioctl_t memioctl;
+d_ioctl_t memioctl_md;
d_mmap_t memmmap;
#endif /* _MACHINE_MEMDEV_H_ */
Index: sys/arm/arm/mem.c
===================================================================
--- sys/arm/arm/mem.c
+++ sys/arm/arm/mem.c
@@ -172,3 +172,10 @@
}
return (-1);
}
+
+int
+memioctl_md(struct cdev *dev __unused, u_long cmd __unused,
+ caddr_t data __unused, int flags __unused, struct thread *td __unused)
+{
+ return (ENOTTY);
+}
Index: sys/arm/include/memdev.h
===================================================================
--- sys/arm/include/memdev.h
+++ sys/arm/include/memdev.h
@@ -37,6 +37,6 @@
d_open_t memopen;
d_read_t memrw;
d_mmap_t memmmap;
-#define memioctl (d_ioctl_t *)NULL
+d_ioctl_t memioctl_md;
#endif /* _MACHINE_MEMDEV_H_ */
Index: sys/arm64/arm64/mem.c
===================================================================
--- sys/arm64/arm64/mem.c
+++ sys/arm64/arm64/mem.c
@@ -129,3 +129,10 @@
}
return (-1);
}
+
+int
+memioctl_md(struct cdev *dev __unused, u_long cmd __unused,
+ caddr_t data __unused, int flags __unused, struct thread *td __unused)
+{
+ return (ENOTTY);
+}
Index: sys/arm64/include/memdev.h
===================================================================
--- sys/arm64/include/memdev.h
+++ sys/arm64/include/memdev.h
@@ -34,7 +34,7 @@
d_open_t memopen;
d_read_t memrw;
-#define memioctl (d_ioctl_t *)NULL
+d_ioctl_t memioctl_md;
d_mmap_t memmmap;
#endif /* _MACHINE_MEMDEV_H_ */
Index: sys/dev/mem/memdev.c
===================================================================
--- sys/dev/mem/memdev.c
+++ sys/dev/mem/memdev.c
@@ -33,6 +33,7 @@
#include <sys/param.h>
#include <sys/conf.h>
#include <sys/fcntl.h>
+#include <sys/ioccom.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
@@ -46,12 +47,19 @@
#include <sys/uio.h>
#include <vm/vm.h>
+#include <vm/vm_param.h>
#include <vm/pmap.h>
+#include <vm/vm_map.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_phys.h>
#include <machine/memdev.h>
static struct cdev *memdev, *kmemdev;
+static d_ioctl_t memioctl;
+
static struct cdevsw mem_cdevsw = {
.d_version = D_VERSION,
.d_flags = D_MEM,
@@ -82,6 +90,32 @@
return (error);
}
+static int
+memioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags,
+ struct thread *td)
+{
+ struct mem_extract *me;
+ int error;
+
+ error = 0;
+ switch (cmd) {
+ case MEM_EXTRACT_PADDR:
+ me = (struct mem_extract *)data;
+
+ me->me_paddr = pmap_extract(&td->td_proc->p_vmspace->vm_pmap,
+ me->me_vaddr);
+ if (me->me_paddr == 0)
+ error = ENOENT;
+ else
+ me->me_domain = _vm_phys_domain(me->me_paddr);
+ break;
+ default:
+ error = memioctl_md(dev, cmd, data, flags, td);
+ break;
+ }
+ return (error);
+}
+
/* ARGSUSED */
static int
mem_modevent(module_t mod __unused, int type, void *data __unused)
Index: sys/i386/i386/mem.c
===================================================================
--- sys/i386/i386/mem.c
+++ sys/i386/i386/mem.c
@@ -177,9 +177,8 @@
* This is basically just an ioctl shim for mem_range_attr_get
* and mem_range_attr_set.
*/
-/* ARGSUSED */
int
-memioctl(struct cdev *dev __unused, u_long cmd, caddr_t data, int flags,
+memioctl_md(struct cdev *dev __unused, u_long cmd, caddr_t data, int flags,
struct thread *td)
{
int nd, error = 0;
Index: sys/i386/include/memdev.h
===================================================================
--- sys/i386/include/memdev.h
+++ sys/i386/include/memdev.h
@@ -36,7 +36,7 @@
d_open_t memopen;
d_read_t memrw;
-d_ioctl_t memioctl;
+d_ioctl_t memioctl_md;
d_mmap_t memmmap;
#endif /* _MACHINE_MEMDEV_H_ */
Index: sys/mips/include/memdev.h
===================================================================
--- sys/mips/include/memdev.h
+++ sys/mips/include/memdev.h
@@ -37,7 +37,7 @@
d_open_t memopen;
d_read_t memrw;
-#define memioctl (d_ioctl_t *)NULL
+d_ioctl_t memioctl_md
d_mmap_t memmmap;
#endif /* _MACHINE_MEMDEV_H_ */
Index: sys/powerpc/include/memdev.h
===================================================================
--- sys/powerpc/include/memdev.h
+++ sys/powerpc/include/memdev.h
@@ -36,7 +36,7 @@
d_open_t memopen;
d_read_t memrw;
-d_ioctl_t memioctl;
+d_ioctl_t memioctl_md;
d_mmap_t memmmap;
#endif /* _MACHINE_MEMDEV_H_ */
Index: sys/powerpc/powerpc/mem.c
===================================================================
--- sys/powerpc/powerpc/mem.c
+++ sys/powerpc/powerpc/mem.c
@@ -278,9 +278,8 @@
* This is basically just an ioctl shim for mem_range_attr_get
* and mem_range_attr_set.
*/
-/* ARGSUSED */
int
-memioctl(struct cdev *dev __unused, u_long cmd, caddr_t data, int flags,
+memioctl_md(struct cdev *dev __unused, u_long cmd, caddr_t data, int flags,
struct thread *td)
{
int nd, error = 0;
Index: sys/riscv/include/memdev.h
===================================================================
--- sys/riscv/include/memdev.h
+++ sys/riscv/include/memdev.h
@@ -34,7 +34,7 @@
d_open_t memopen;
d_read_t memrw;
-#define memioctl (d_ioctl_t *)NULL
+d_ioctl_t memioctl_md;
#define memmmap (d_mmap_t *)NULL
#endif /* _MACHINE_MEMDEV_H_ */
Index: sys/riscv/riscv/mem.c
===================================================================
--- sys/riscv/riscv/mem.c
+++ sys/riscv/riscv/mem.c
@@ -122,3 +122,9 @@
return (error);
}
+int
+memioctl_md(struct cdev *dev __unused, u_long cmd __unused,
+ caddr_t data __unused, int flags __unused, struct thread *td __unused)
+{
+ return (ENOTTY);
+}
Index: sys/sys/memrange.h
===================================================================
--- sys/sys/memrange.h
+++ sys/sys/memrange.h
@@ -45,6 +45,16 @@
#define MEMRANGE_GET _IOWR('m', 50, struct mem_range_op)
#define MEMRANGE_SET _IOW('m', 51, struct mem_range_op)
+struct mem_extract {
+ uint64_t me_vaddr;
+ uint64_t me_paddr;
+ int me_domain;
+ uint32_t pad0;
+ uint64_t pad1[5];
+};
+
+#define MEM_EXTRACT_PADDR _IOWR('m', 52, struct mem_extract)
+
#ifdef _KERNEL
MALLOC_DECLARE(M_MEMDESC);

File Metadata

Mime Type
text/plain
Expires
Wed, Feb 18, 11:25 PM (12 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28859359
Default Alt Text
D26237.id76377.diff (9 KB)

Event Timeline