memdev.c revision 278746
11558Srgrimes/*-
21558Srgrimes * Copyright (c) 2004 Mark R V Murray
31558Srgrimes * All rights reserved.
41558Srgrimes *
51558Srgrimes * Redistribution and use in source and binary forms, with or without
61558Srgrimes * modification, are permitted provided that the following conditions
71558Srgrimes * are met:
81558Srgrimes * 1. Redistributions of source code must retain the above copyright
91558Srgrimes *    notice, this list of conditions and the following disclaimer
101558Srgrimes *    in this position and unchanged.
111558Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
121558Srgrimes *    notice, this list of conditions and the following disclaimer in the
131558Srgrimes *    documentation and/or other materials provided with the distribution.
141558Srgrimes *
151558Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
161558Srgrimes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
171558Srgrimes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
181558Srgrimes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
191558Srgrimes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
201558Srgrimes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
211558Srgrimes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
221558Srgrimes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
231558Srgrimes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
241558Srgrimes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
251558Srgrimes *
261558Srgrimes */
271558Srgrimes
281558Srgrimes#include <sys/cdefs.h>
291558Srgrimes__FBSDID("$FreeBSD: stable/10/sys/dev/mem/memdev.c 278746 2015-02-14 08:44:12Z kib $");
30114589Sobrien
311558Srgrimes#include <sys/param.h>
327585Sbde#include <sys/conf.h>
331558Srgrimes#include <sys/fcntl.h>
341558Srgrimes#include <sys/kernel.h>
351558Srgrimes#include <sys/lock.h>
361558Srgrimes#include <sys/malloc.h>
371558Srgrimes#include <sys/memrange.h>
3841477Sjulian#include <sys/module.h>
39114589Sobrien#include <sys/mutex.h>
4041477Sjulian#include <sys/priv.h>
4193103Smarkm#include <sys/proc.h>
4293103Smarkm#include <sys/signalvar.h>
4393103Smarkm#include <sys/systm.h>
441558Srgrimes#include <sys/uio.h>
4555275Speter
4675557Smckusick#include <vm/vm.h>
471558Srgrimes#include <vm/pmap.h>
481558Srgrimes
4940918Smjacob#include <machine/memdev.h>
5086514Siedowse
51172236Srodrigcstatic struct cdev *memdev, *kmemdev;
5298542Smckusick
5323675Speterstatic struct cdevsw mem_cdevsw = {
541558Srgrimes	.d_version =	D_VERSION,
551558Srgrimes	.d_flags =	D_MEM,
5623675Speter	.d_open =	memopen,
5723675Speter	.d_read =	memrw,
5855725Speter	.d_write =	memrw,
591558Srgrimes	.d_ioctl =	memioctl,
60120901Smckusick	.d_mmap =	memmmap,
61172236Srodrigc	.d_name =	"mem",
6255725Speter};
63101037Smux
6486514Siedowse/* ARGSUSED */
6523675Speterint
661558Srgrimesmemopen(struct cdev *dev __unused, int flags, int fmt __unused,
671558Srgrimes    struct thread *td)
6892839Simp{
69100935Sphk	int error = 0;
7092839Simp
71171800Spjd	if (flags & FREAD)
7292839Simp		error = priv_check(td, PRIV_KMEM_READ);
7323675Speter	if (flags & FWRITE) {
747585Sbde		if (error == 0)
7592839Simp			error = priv_check(td, PRIV_KMEM_WRITE);
761558Srgrimes		if (error == 0)
771558Srgrimes			error = securelevel_gt(td->td_ucred, 0);
7841474Sjulian	}
79126345Sscottl
8066861Sadrian	return (error);
811558Srgrimes}
821558Srgrimes
8366861Sadrian/* ARGSUSED */
84188110Smckusickstatic int
85188110Smckusickmem_modevent(module_t mod __unused, int type, void *data __unused)
861558Srgrimes{
871558Srgrimes	switch(type) {
8866861Sadrian	case MOD_LOAD:
891558Srgrimes		if (bootverbose)
901558Srgrimes			printf("mem: <memory>\n");
911558Srgrimes		mem_range_init();
921558Srgrimes		memdev = make_dev(&mem_cdevsw, CDEV_MINOR_MEM,
9374556Smckusick			UID_ROOT, GID_KMEM, 0640, "mem");
9474556Smckusick		kmemdev = make_dev(&mem_cdevsw, CDEV_MINOR_KMEM,
9574556Smckusick			UID_ROOT, GID_KMEM, 0640, "kmem");
9674556Smckusick		break;
971558Srgrimes
9866861Sadrian	case MOD_UNLOAD:
991558Srgrimes		mem_range_destroy();
10098542Smckusick		destroy_dev(memdev);
10198542Smckusick		destroy_dev(kmemdev);
10298542Smckusick		break;
1031558Srgrimes
1048871Srgrimes	case MOD_SHUTDOWN:
1051558Srgrimes		break;
1061558Srgrimes
1071558Srgrimes	default:
1081558Srgrimes		return(EOPNOTSUPP);
1092153Sdg
11066861Sadrian	}
1112153Sdg
1122153Sdg	return (0);
11375927Smckusick}
11475927Smckusick
11575927SmckusickDEV_MODULE(mem, mem_modevent, NULL);
11675927SmckusickMODULE_VERSION(mem, 1);
1171558Srgrimes