Xen & Linux KernelProgramming Adding a System CallIonut ConstandacheWhat is Xen?A virtual machine monitor (VMM) for x86-compatible computers Run multiple instances of OSes simultaneouslyThese are called Guest OSes Provides isolation between Guest OSes Uses ParavirtualizationDoes not hide virtualization from the Guest OSes OS must be ported to work with XenXen system structureXen is lowest, most privileged system levelXen hosts multiple Guest OSes (called domains in Xen) running in secure VMsDomain 0 – special privileged management domainBuilds other domains and manages their virtual devices The domain you are logging in to when you ssh to cps210.cod.cs.duke.eduUsing Xen in CPS 110Xen machine: cps210.cod.cs.duke.eduEach team/student has an account on cps210ssh into cps210.cod.cs.duke.edussh [email protected] /usr/research/proj/cps110Source files for linux kernel 2.6.16.29 linux-2.6.16.29-xenU.tar -> copy it to your home directoryThe configuration file for running a DomU virtual machineTeamName.xen -> copy it to your home directorytar -xvf linux-2.6.16.29-xenU.tar -> extract source filesThe xm utilityCommand line utility to control guestsTo start a machine:(sudo) /usr/sbin/xm create -c teamname.xen the machine will start -> you can login into it with root (no password)exit from the machine ctrl-5 (control returns to Dom0)To list the machines currently running (sudo) xm listTo destroy a DomU guest machine(sudo) xm destroy machineID (from xm list)Adding a system callObjectives: Keep track of how many times each of the fork, vfork, execve and clone system calls is invokedPlace counters in kernel codeImplement a new system call providing this informationRequest/retrieve these values from user space by invoking the new system call/sSystem call recap'The system call number is pushed into a registerTrap instruction/software interrupt to switch from user mode to kernel modeKernel takes the system call number, indexes into the table of system calls, and executes the system call handler (eax) (syscall_table) (object code) __NR_syscall -> syscallname -> syscallname codeAdding a system call (1)Defining the syscall_No Edit include/asm-i386/unistd.hcontents:#define __NR_restart_syscall 0#define __NR_exit 1#define __NR_fork 2#define __NR_read 3#define __NR_unshare 310#define __NR_mysyscall 311 <- add the next syscall_NO#define NR_syscalls 312 <- modify the number of available system callsAdding a system call (2)Add the system call to the syscall_tableEdit arch/i386/kernel/syscall_table.Scontents:.long sys_restart_syscall .long sys_exit.long sys_fork.long sys_read.........................long sys_unshare /* 310 */.long sys_mysyscall <- add an entry to the last line (this is going to be the new system call)Adding a system call (3)Add the system call to syscalls prototype header fileEdit include/linux/syscalls.hcontents:................ asmlinkage long sys_mysyscall(unsigned int cmd); <- add the system call at the end of the file #endifAdding a system call (3)You can place the system call in a file that gets linked into the kernelCleaner - define your own file and modify the kernel Makefile to include the object code of your definitionCreate a directory mysyscall in the kernel source file root directory(linux-2.6.16.29-xenU)Adding a system call (4)In the directory mysyscallCreate a file mysyscall.cCreate a file MakefileEdit mysyscall.c#include <linux/kernel.h>asmlinkage long sys_mysyscall(unsigned int cmd){ printk(KERN_DEBUG "cmd = %d\n",cmd); return 0;} Edit Makefileobj-y := mysyscall.oAdding a system call (5)Edit the Makefile in Linux source file root directoryRun make in Linux source file root directLook for core-y += Add mysyscall/ core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ mysyscall/Run make in Linux source file root directoryIn mysyscall/ -> an object file mysyscall.oLinux image is in vmlinuzRun the VMEdit TeamName.xen file Replace kernel = "/usr/research/proj/cps110/vmlinuz-xenU" with the path to your new kernel image(kernel = "/usr/research/home/Team/linux-2.6.16.29-xenU/vmlinuz")Run the virtual machine with the new kernel(sudo) xm create -c teamname.xenInvoke the system callIn your VM create a file test.c#include <sys/syscall.h>#include <stdio.h>#define __NR_mysyscall 311int main(){syscall(__NR_mysyscall,1);return 0;}Compile it!Run dmesg (displays kernel messages)You should see the output printed by your system callTipsThe fork, vfork, execve and clone system calls are implemented in arch/i386/kernel/process(-xen).c Your counters should be placed in this fileIn order to get the counters in mysyscal.c you have to make them accessible (e.g define them extern in kernel.h)Tips IIKernel 2.6 is preemptive you should protect the counters with locks (use spinlocks)spinlock_t -> Ch 15 in Linux Device Drivers 3rd Ed.If you need to allocate memory the kernel function is kmallocchar* ptr = kmalloc(10*sizeof(char), GFP_KERNEL) kfree(ptr);Ch 8 in Linux Device Driver 3rd Ed.Tips IIIUser Space/Kernel Space memory – move system calls arguments to and from user spaceSanity checks: (#include <asm/uaccess.h>)int access_ok(type, ptr, size); (return 1 if OK)type VERIFY_READ/VERIFY_WRITEsize in bytesptr -> pointer to user space memoryCopying data get_user, put_user (for simple data types)Ex: put_user(char, char*) (check return value == 0 ok!)copy_from_user, copy_to_userEx: copy_from_user(char *to, char __user *from, unsigned long size)Tips IVError codes:Convention: if a function returns 0 -> successany other value failureYou should write code using this conventionErrors that kernel functions/system call should return are defined errno.h (#include <asm/errno.h>)Always return -ERRORCODE (e.g. -EINVAL, -EFAULT)ReferencesLinux Device Drivers 3rd Editionhttp://lwn.net/Kernel/LDD3/Linux Kernel Source Tree
View Full Document