lguest_user.c revision e1e72965ec2c02db99b415cd06c17ea90767e3a4
1f938d2c892db0d80d144253d4a7b7083efdbedebRusty Russell/*P:200 This contains all the /dev/lguest code, whereby the userspace launcher 2f938d2c892db0d80d144253d4a7b7083efdbedebRusty Russell * controls and communicates with the Guest. For example, the first write will 33c6b5bfa3cf3b4057788e08482a468cc3bc00780Rusty Russell * tell us the Guest's memory layout, pagetable, entry point and kernel address 43c6b5bfa3cf3b4057788e08482a468cc3bc00780Rusty Russell * offset. A read will run the Guest until something happens, such as a signal 515045275c32bf6d15d32c2eca8157be9c0ba6e45Rusty Russell * or the Guest doing a NOTIFY out to the Launcher. :*/ 6d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell#include <linux/uaccess.h> 7d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell#include <linux/miscdevice.h> 8d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell#include <linux/fs.h> 9d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell#include "lg.h" 10d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 11e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell/*L:055 When something happens, the Waker process needs a way to stop the 12e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell * kernel running the Guest and return to the Launcher. So the Waker writes 13e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell * LHREQ_BREAK and the value "1" to /dev/lguest to do this. Once the Launcher 14e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell * has done whatever needs attention, it writes LHREQ_BREAK and "0" to release 15e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell * the Waker. */ 16511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensenstatic int break_guest_out(struct lguest *lg, const unsigned long __user *input) 17d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell{ 18d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell unsigned long on; 19d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 20e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell /* Fetch whether they're turning break on or off. */ 21d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (get_user(on, input) != 0) 22d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return -EFAULT; 23d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 24d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (on) { 25d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell lg->break_out = 1; 26e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell /* Pop it out of the Guest (may be running on different CPU) */ 27d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell wake_up_process(lg->tsk); 28d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell /* Wait for them to reset it */ 29d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return wait_event_interruptible(lg->break_wq, !lg->break_out); 30d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } else { 31d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell lg->break_out = 0; 32d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell wake_up(&lg->break_wq); 33d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return 0; 34d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } 35d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell} 36d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 37dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell/*L:050 Sending an interrupt is done by writing LHREQ_IRQ and an interrupt 38dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * number to /dev/lguest. */ 39511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensenstatic int user_send_irq(struct lguest *lg, const unsigned long __user *input) 40d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell{ 41511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensen unsigned long irq; 42d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 43d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (get_user(irq, input) != 0) 44d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return -EFAULT; 45d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (irq >= LGUEST_IRQS) 46d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return -EINVAL; 47dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* Next time the Guest runs, the core code will see if it can deliver 48dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * this interrupt. */ 49d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell set_bit(irq, lg->irqs_pending); 50d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return 0; 51d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell} 52d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 53dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell/*L:040 Once our Guest is initialized, the Launcher makes it run by reading 54dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * from /dev/lguest. */ 55d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russellstatic ssize_t read(struct file *file, char __user *user, size_t size,loff_t*o) 56d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell{ 57d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell struct lguest *lg = file->private_data; 58d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 59dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* You must write LHREQ_INITIALIZE first! */ 60d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (!lg) 61d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return -EINVAL; 62d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 63e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell /* If you're not the task which owns the Guest, go away. */ 64d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (current != lg->tsk) 65d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return -EPERM; 66d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 67dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* If the guest is already dead, we indicate why */ 68d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (lg->dead) { 69d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell size_t len; 70d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 71dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* lg->dead either contains an error code, or a string. */ 72d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (IS_ERR(lg->dead)) 73d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return PTR_ERR(lg->dead); 74d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 75dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* We can only return as much as the buffer they read with. */ 76d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell len = min(size, strlen(lg->dead)+1); 77d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (copy_to_user(user, lg->dead, len) != 0) 78d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return -EFAULT; 79d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return len; 80d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } 81d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 8215045275c32bf6d15d32c2eca8157be9c0ba6e45Rusty Russell /* If we returned from read() last time because the Guest notified, 83dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * clear the flag. */ 8415045275c32bf6d15d32c2eca8157be9c0ba6e45Rusty Russell if (lg->pending_notify) 8515045275c32bf6d15d32c2eca8157be9c0ba6e45Rusty Russell lg->pending_notify = 0; 86d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 87dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* Run the Guest until something interesting happens. */ 88d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return run_guest(lg, (unsigned long __user *)user); 89d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell} 90d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 9147436aa4ad054c1c7c8231618e86ebd9305308dcRusty Russell/*L:020 The initialization write supplies 4 pointer sized (32 or 64 bit) 92511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensen * values (in addition to the LHREQ_INITIALIZE value). These are: 93dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * 943c6b5bfa3cf3b4057788e08482a468cc3bc00780Rusty Russell * base: The start of the Guest-physical memory inside the Launcher memory. 953c6b5bfa3cf3b4057788e08482a468cc3bc00780Rusty Russell * 96dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * pfnlimit: The highest (Guest-physical) page number the Guest should be 97e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell * allowed to access. The Guest memory lives inside the Launcher, so it sets 98e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell * this to ensure the Guest can only reach its own memory. 99dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * 100dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * pgdir: The (Guest-physical) address of the top of the initial Guest 101dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * pagetables (which are set up by the Launcher). 102dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * 103dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * start: The first instruction to execute ("eip" in x86-speak). 104dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell */ 105511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensenstatic int initialize(struct file *file, const unsigned long __user *input) 106d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell{ 107dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* "struct lguest" contains everything we (the Host) know about a 108dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * Guest. */ 109d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell struct lguest *lg; 11048245cc0708d49d1d0566b9fa617ad6c5f4c6934Rusty Russell int err; 11147436aa4ad054c1c7c8231618e86ebd9305308dcRusty Russell unsigned long args[4]; 112d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 11348245cc0708d49d1d0566b9fa617ad6c5f4c6934Rusty Russell /* We grab the Big Lguest lock, which protects against multiple 11448245cc0708d49d1d0566b9fa617ad6c5f4c6934Rusty Russell * simultaneous initializations. */ 115d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell mutex_lock(&lguest_lock); 116dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* You can't initialize twice! Close the device and start again... */ 117d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (file->private_data) { 118d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell err = -EBUSY; 119d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell goto unlock; 120d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } 121d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 122d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (copy_from_user(args, input, sizeof(args)) != 0) { 123d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell err = -EFAULT; 124d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell goto unlock; 125d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } 126d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 12748245cc0708d49d1d0566b9fa617ad6c5f4c6934Rusty Russell lg = kzalloc(sizeof(*lg), GFP_KERNEL); 12848245cc0708d49d1d0566b9fa617ad6c5f4c6934Rusty Russell if (!lg) { 12948245cc0708d49d1d0566b9fa617ad6c5f4c6934Rusty Russell err = -ENOMEM; 130d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell goto unlock; 131d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } 132dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell 133dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* Populate the easy fields of our "struct lguest" */ 1343c6b5bfa3cf3b4057788e08482a468cc3bc00780Rusty Russell lg->mem_base = (void __user *)(long)args[0]; 1353c6b5bfa3cf3b4057788e08482a468cc3bc00780Rusty Russell lg->pfn_limit = args[1]; 136dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell 137dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* We need a complete page for the Guest registers: they are accessible 138dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * to the Guest and we can only grant it access to whole pages. */ 139d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell lg->regs_page = get_zeroed_page(GFP_KERNEL); 140d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (!lg->regs_page) { 141d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell err = -ENOMEM; 142d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell goto release_guest; 143d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } 144dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* We actually put the registers at the bottom of the page. */ 145d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell lg->regs = (void *)lg->regs_page + PAGE_SIZE - sizeof(*lg->regs); 146d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 147dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* Initialize the Guest's shadow page tables, using the toplevel 148dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * address the Launcher gave us. This allocates memory, so can 149dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * fail. */ 1503c6b5bfa3cf3b4057788e08482a468cc3bc00780Rusty Russell err = init_guest_pagetable(lg, args[2]); 151d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (err) 152d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell goto free_regs; 153d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 154dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* Now we initialize the Guest's registers, handing it the start 155dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * address. */ 156d612cde060a005c1effb13d0f665448a04ce5f67Jes Sorensen lguest_arch_setup_regs(lg, args[3]); 157dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell 158dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* The timer for lguest's clock needs initialization. */ 159d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell init_clockdev(lg); 160dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell 161dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* We keep a pointer to the Launcher task (ie. current task) for when 162dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * other Guests want to wake this one (inter-Guest I/O). */ 163d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell lg->tsk = current; 164dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* We need to keep a pointer to the Launcher's memory map, because if 165dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * the Launcher dies we need to clean it up. If we don't keep a 166dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * reference, it is destroyed before close() is called. */ 167d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell lg->mm = get_task_mm(lg->tsk); 168dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell 169dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* Initialize the queue for the waker to wait on */ 170d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell init_waitqueue_head(&lg->break_wq); 171dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell 172dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* We remember which CPU's pages this Guest used last, for optimization 173dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * when the same Guest runs on the same CPU twice. */ 174d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell lg->last_pages = NULL; 175dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell 176dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* We keep our "struct lguest" in the file's private_data. */ 177d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell file->private_data = lg; 178d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 179d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell mutex_unlock(&lguest_lock); 180d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 181dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* And because this is a write() call, we return the length used. */ 182d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return sizeof(args); 183d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 184d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russellfree_regs: 185d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell free_page(lg->regs_page); 186d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russellrelease_guest: 187d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell memset(lg, 0, sizeof(*lg)); 188d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russellunlock: 189d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell mutex_unlock(&lguest_lock); 190d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return err; 191d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell} 192d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 193dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell/*L:010 The first operation the Launcher does must be a write. All writes 194e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell * start with an unsigned long number: for the first write this must be 195dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * LHREQ_INITIALIZE to set up the Guest. After that the Launcher can use 19615045275c32bf6d15d32c2eca8157be9c0ba6e45Rusty Russell * writes of other values to send interrupts. */ 197511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensenstatic ssize_t write(struct file *file, const char __user *in, 198d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell size_t size, loff_t *off) 199d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell{ 200dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* Once the guest is initialized, we hold the "struct lguest" in the 201dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * file private data. */ 202d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell struct lguest *lg = file->private_data; 203511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensen const unsigned long __user *input = (const unsigned long __user *)in; 204511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensen unsigned long req; 205d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 206d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (get_user(req, input) != 0) 207d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return -EFAULT; 208511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensen input++; 209d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 210dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* If you haven't initialized, you must do that first. */ 211d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (req != LHREQ_INITIALIZE && !lg) 212d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return -EINVAL; 213dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell 214dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* Once the Guest is dead, all you can do is read() why it died. */ 215d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (lg && lg->dead) 216d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return -ENOENT; 217d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 218d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell /* If you're not the task which owns the Guest, you can only break */ 219d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (lg && current != lg->tsk && req != LHREQ_BREAK) 220d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return -EPERM; 221d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 222d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell switch (req) { 223d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell case LHREQ_INITIALIZE: 224511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensen return initialize(file, input); 225d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell case LHREQ_IRQ: 226511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensen return user_send_irq(lg, input); 227d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell case LHREQ_BREAK: 228511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensen return break_guest_out(lg, input); 229d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell default: 230d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return -EINVAL; 231d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } 232d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell} 233d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 234dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell/*L:060 The final piece of interface code is the close() routine. It reverses 235dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * everything done in initialize(). This is usually called because the 236dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * Launcher exited. 237dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * 238dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * Note that the close routine returns 0 or a negative error number: it can't 239dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * really fail, but it can whine. I blame Sun for this wart, and K&R C for 240dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * letting them do it. :*/ 241d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russellstatic int close(struct inode *inode, struct file *file) 242d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell{ 243d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell struct lguest *lg = file->private_data; 244d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 245dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* If we never successfully initialized, there's nothing to clean up */ 246d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (!lg) 247d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return 0; 248d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 249dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* We need the big lock, to protect from inter-guest I/O and other 250dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * Launchers initializing guests. */ 251d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell mutex_lock(&lguest_lock); 252d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell /* Cancels the hrtimer set via LHCALL_SET_CLOCKEVENT. */ 253d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell hrtimer_cancel(&lg->hrt); 254dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* Free up the shadow page tables for the Guest. */ 255d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell free_guest_pagetable(lg); 256dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* Now all the memory cleanups are done, it's safe to release the 257dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * Launcher's memory management structure. */ 258d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell mmput(lg->mm); 259dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* If lg->dead doesn't contain an error code it will be NULL or a 260dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * kmalloc()ed string, either of which is ok to hand to kfree(). */ 261d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (!IS_ERR(lg->dead)) 262d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell kfree(lg->dead); 263dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* We can free up the register page we allocated. */ 264d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell free_page(lg->regs_page); 265dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* We clear the entire structure, which also marks it as free for the 266dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * next user. */ 267d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell memset(lg, 0, sizeof(*lg)); 268dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* Release lock and exit. */ 269d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell mutex_unlock(&lguest_lock); 270dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell 271d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return 0; 272d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell} 273d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 274dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell/*L:000 275dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * Welcome to our journey through the Launcher! 276dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * 277dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * The Launcher is the Host userspace program which sets up, runs and services 278dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * the Guest. In fact, many comments in the Drivers which refer to "the Host" 279dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * doing things are inaccurate: the Launcher does all the device handling for 280e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell * the Guest, but the Guest can't know that. 281dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * 282dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * Just to confuse you: to the Host kernel, the Launcher *is* the Guest and we 283dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * shall see more of that later. 284dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * 285dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * We begin our understanding with the Host kernel interface which the Launcher 286dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * uses: reading and writing a character device called /dev/lguest. All the 287dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * work happens in the read(), write() and close() routines: */ 288d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russellstatic struct file_operations lguest_fops = { 289d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell .owner = THIS_MODULE, 290d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell .release = close, 291d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell .write = write, 292d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell .read = read, 293d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell}; 294dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell 295dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell/* This is a textbook example of a "misc" character device. Populate a "struct 296dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * miscdevice" and register it with misc_register(). */ 297d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russellstatic struct miscdevice lguest_dev = { 298d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell .minor = MISC_DYNAMIC_MINOR, 299d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell .name = "lguest", 300d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell .fops = &lguest_fops, 301d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell}; 302d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 303d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russellint __init lguest_device_init(void) 304d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell{ 305d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return misc_register(&lguest_dev); 306d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell} 307d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 308d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russellvoid __exit lguest_device_remove(void) 309d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell{ 310d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell misc_deregister(&lguest_dev); 311d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell} 312