From b262aee7ec33483548b73e8e5373628f60742bdb Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Fri, 24 Jun 2011 20:13:01 +0200 Subject: [PATCH] Move u2mfn from gui repo --- u2mfn/.gitignore | 9 +++ u2mfn/Makefile | 28 ++++++++ u2mfn/buildme.sh | 25 ++++++++ u2mfn/cleanup.sh | 2 + u2mfn/u2mfn.c | 163 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 227 insertions(+) create mode 100644 u2mfn/.gitignore create mode 100644 u2mfn/Makefile create mode 100755 u2mfn/buildme.sh create mode 100755 u2mfn/cleanup.sh create mode 100644 u2mfn/u2mfn.c diff --git a/u2mfn/.gitignore b/u2mfn/.gitignore new file mode 100644 index 0000000..0b09e96 --- /dev/null +++ b/u2mfn/.gitignore @@ -0,0 +1,9 @@ +.tmp_versions/ +.u2mfn.ko.cmd +.u2mfn.mod.o.cmd +.u2mfn.o.cmd +Makefile.xen +Module.symvers +modules.order +u2mfn.ko +u2mfn.mod.c diff --git a/u2mfn/Makefile b/u2mfn/Makefile new file mode 100644 index 0000000..59e222d --- /dev/null +++ b/u2mfn/Makefile @@ -0,0 +1,28 @@ +# +# The Qubes OS Project, http://www.qubes-os.org +# +# Copyright (C) 2010 Rafal Wojtczuk +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# + +obj-m += u2mfn.o + +clean: + rm -f *.o *.ko *~ + rm -f .u2mfn.* *.mod.c Module.symvers modules.order + rm -fr .tmp_versions + rm -f Makefile.xen diff --git a/u2mfn/buildme.sh b/u2mfn/buildme.sh new file mode 100755 index 0000000..cc332e9 --- /dev/null +++ b/u2mfn/buildme.sh @@ -0,0 +1,25 @@ +#!/bin/sh +# +# The Qubes OS Project, http://www.qubes-os.org +# +# Copyright (C) 2010 Rafal Wojtczuk +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# + + +make -C /lib/modules/`uname -r`/build/ SUBDIRS=`pwd` modules \ + EXTRA_CFLAGS=-I`pwd`/../xenincl \ No newline at end of file diff --git a/u2mfn/cleanup.sh b/u2mfn/cleanup.sh new file mode 100755 index 0000000..ea9352d --- /dev/null +++ b/u2mfn/cleanup.sh @@ -0,0 +1,2 @@ +#!/bin/sh +make -C /lib/modules/`uname -r`/build/ SUBDIRS=`pwd` clean diff --git a/u2mfn/u2mfn.c b/u2mfn/u2mfn.c new file mode 100644 index 0000000..80a1d0b --- /dev/null +++ b/u2mfn/u2mfn.c @@ -0,0 +1,163 @@ +/* + * The Qubes OS Project, http://www.qubes-os.org + * + * Copyright (C) 2010 Rafal Wojtczuk + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include +#include +#include +#ifndef FOREIGN_FRAME_BIT +#include +#endif +#include +#include "/usr/include/u2mfn-kernel.h" + +static inline unsigned long virt_to_phys(volatile void *address) +{ + return __pa((unsigned long) address); +} + +#if HAVE_GET_PHYS_TO_MACHINE +#define VIRT_TO_MFN virt_to_mfn +#else +extern unsigned long *phys_to_machine_mapping; +static inline unsigned long VIRT_TO_MFN(void *addr) +{ + unsigned int pfn = virt_to_phys(addr) >> PAGE_SHIFT; + return phys_to_machine_mapping[pfn] & ~FOREIGN_FRAME_BIT; +} +#endif + +/// User virtual address to mfn translator +/** + \param cmd ignored + \param data the user-specified address + \return mfn corresponding to "data" argument, or -1 on error +*/ +static long u2mfn_ioctl(struct file *f, unsigned int cmd, + unsigned long data) +{ + struct page *user_page; + void *kaddr; + int ret; + + if (_IOC_TYPE(cmd) != U2MFN_MAGIC) { + printk("Qubes u2mfn: wrong IOCTL magic"); + return -ENOTTY; + } + + switch (cmd) { + case U2MFN_GET_MFN_FOR_PAGE: + down_read(¤t->mm->mmap_sem); + ret = get_user_pages + (current, current->mm, data, 1, 1, 0, &user_page, 0); + up_read(¤t->mm->mmap_sem); + if (ret != 1) { + printk("U2MFN_GET_MFN_FOR_PAGE: get_user_pages failed, ret=0x%x\n", ret); + return -1; + } + kaddr = kmap(user_page); + ret = VIRT_TO_MFN(kaddr); + kunmap(user_page); + put_page(user_page); + break; + + case U2MFN_GET_LAST_MFN: + if (f->private_data) + ret = VIRT_TO_MFN(f->private_data); + else + ret = 0; + break; + + default: + printk("Qubes u2mfn: wrong ioctl passed!\n"); + return -ENOTTY; + } + + + return ret; +} + +static int u2mfn_mmap(struct file *f, struct vm_area_struct *vma) +{ + int ret; + char *kbuf; + long length = vma->vm_end - vma->vm_start; + printk("u2mfn_mmap: entering, private=%p\n", f->private_data); + if (f->private_data) + return -EBUSY; + if (length != PAGE_SIZE) + return -EINVAL; + kbuf = (char *) __get_free_page(GFP_KERNEL); + if (!kbuf) + return -ENOMEM; + + f->private_data = kbuf; + + ret = remap_pfn_range(vma, vma->vm_start, + virt_to_phys(kbuf) >> PAGE_SHIFT, + length, vma->vm_page_prot); + + printk("u2mfn_mmap: calling remap return %d\n", ret); + if (ret) + return ret; + + + return 0; +} + +static int u2mfn_release(struct inode *i, struct file *f) +{ + printk("u2mfn_release, priv=%p\n", f->private_data); + if (f->private_data) + __free_page(f->private_data); + f->private_data = NULL; + return 0; +} + +static struct file_operations u2mfn_fops = { + .unlocked_ioctl = u2mfn_ioctl, + .mmap = u2mfn_mmap, + .release = u2mfn_release +}; + +/// u2mfn module registration +/** + tries to register "/proc/u2mfn" pseudofile +*/ +static int u2mfn_init(void) +{ + struct proc_dir_entry *u2mfn_node = + proc_create_data("u2mfn", 0600, NULL, + &u2mfn_fops, 0); + if (!u2mfn_node) + return -1; + return 0; +} + +static void u2mfn_exit(void) +{ + remove_proc_entry("u2mfn", 0); +} + +module_init(u2mfn_init); +module_exit(u2mfn_exit); +MODULE_LICENSE("GPL");