lguest_user.c revision 7ea07a1500f05e06ebf0136763c781244f77a2a1
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; 58d0953d42c3445a120299fac9ad70e672d77898e9Glauber de Oliveira Costa struct lg_cpu *cpu; 59d0953d42c3445a120299fac9ad70e672d77898e9Glauber de Oliveira Costa unsigned int cpu_id = *o; 60d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 61dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* You must write LHREQ_INITIALIZE first! */ 62d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (!lg) 63d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return -EINVAL; 64d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 65d0953d42c3445a120299fac9ad70e672d77898e9Glauber de Oliveira Costa /* Watch out for arbitrary vcpu indexes! */ 66d0953d42c3445a120299fac9ad70e672d77898e9Glauber de Oliveira Costa if (cpu_id >= lg->nr_cpus) 67d0953d42c3445a120299fac9ad70e672d77898e9Glauber de Oliveira Costa return -EINVAL; 68d0953d42c3445a120299fac9ad70e672d77898e9Glauber de Oliveira Costa 69d0953d42c3445a120299fac9ad70e672d77898e9Glauber de Oliveira Costa cpu = &lg->cpus[cpu_id]; 70d0953d42c3445a120299fac9ad70e672d77898e9Glauber de Oliveira Costa 71e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell /* If you're not the task which owns the Guest, go away. */ 72d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (current != lg->tsk) 73d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return -EPERM; 74d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 75dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* If the guest is already dead, we indicate why */ 76d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (lg->dead) { 77d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell size_t len; 78d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 79dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* lg->dead either contains an error code, or a string. */ 80d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (IS_ERR(lg->dead)) 81d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return PTR_ERR(lg->dead); 82d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 83dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* We can only return as much as the buffer they read with. */ 84d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell len = min(size, strlen(lg->dead)+1); 85d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (copy_to_user(user, lg->dead, len) != 0) 86d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return -EFAULT; 87d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return len; 88d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } 89d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 9015045275c32bf6d15d32c2eca8157be9c0ba6e45Rusty Russell /* If we returned from read() last time because the Guest notified, 91dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * clear the flag. */ 9215045275c32bf6d15d32c2eca8157be9c0ba6e45Rusty Russell if (lg->pending_notify) 9315045275c32bf6d15d32c2eca8157be9c0ba6e45Rusty Russell lg->pending_notify = 0; 94d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 95dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* Run the Guest until something interesting happens. */ 96d0953d42c3445a120299fac9ad70e672d77898e9Glauber de Oliveira Costa return run_guest(cpu, (unsigned long __user *)user); 97d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell} 98d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 994dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costastatic int lg_cpu_start(struct lg_cpu *cpu, unsigned id, unsigned long start_ip) 1004dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa{ 1014dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa if (id >= NR_CPUS) 1024dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa return -EINVAL; 1034dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa 1044dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa cpu->id = id; 1054dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa cpu->lg = container_of((cpu - id), struct lguest, cpus[0]); 1064dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa cpu->lg->nr_cpus++; 1074dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa 1084dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa return 0; 1094dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa} 1104dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa 11147436aa4ad054c1c7c8231618e86ebd9305308dcRusty Russell/*L:020 The initialization write supplies 4 pointer sized (32 or 64 bit) 112511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensen * values (in addition to the LHREQ_INITIALIZE value). These are: 113dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * 1143c6b5bfa3cf3b4057788e08482a468cc3bc00780Rusty Russell * base: The start of the Guest-physical memory inside the Launcher memory. 1153c6b5bfa3cf3b4057788e08482a468cc3bc00780Rusty Russell * 116dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * pfnlimit: The highest (Guest-physical) page number the Guest should be 117e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell * allowed to access. The Guest memory lives inside the Launcher, so it sets 118e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell * this to ensure the Guest can only reach its own memory. 119dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * 120dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * pgdir: The (Guest-physical) address of the top of the initial Guest 121dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * pagetables (which are set up by the Launcher). 122dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * 123dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * start: The first instruction to execute ("eip" in x86-speak). 124dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell */ 125511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensenstatic int initialize(struct file *file, const unsigned long __user *input) 126d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell{ 127dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* "struct lguest" contains everything we (the Host) know about a 128dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * Guest. */ 129d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell struct lguest *lg; 13048245cc0708d49d1d0566b9fa617ad6c5f4c6934Rusty Russell int err; 13147436aa4ad054c1c7c8231618e86ebd9305308dcRusty Russell unsigned long args[4]; 132d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 13348245cc0708d49d1d0566b9fa617ad6c5f4c6934Rusty Russell /* We grab the Big Lguest lock, which protects against multiple 13448245cc0708d49d1d0566b9fa617ad6c5f4c6934Rusty Russell * simultaneous initializations. */ 135d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell mutex_lock(&lguest_lock); 136dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* You can't initialize twice! Close the device and start again... */ 137d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (file->private_data) { 138d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell err = -EBUSY; 139d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell goto unlock; 140d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } 141d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 142d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (copy_from_user(args, input, sizeof(args)) != 0) { 143d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell err = -EFAULT; 144d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell goto unlock; 145d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } 146d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 14748245cc0708d49d1d0566b9fa617ad6c5f4c6934Rusty Russell lg = kzalloc(sizeof(*lg), GFP_KERNEL); 14848245cc0708d49d1d0566b9fa617ad6c5f4c6934Rusty Russell if (!lg) { 14948245cc0708d49d1d0566b9fa617ad6c5f4c6934Rusty Russell err = -ENOMEM; 150d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell goto unlock; 151d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } 152dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell 153dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* Populate the easy fields of our "struct lguest" */ 1543c6b5bfa3cf3b4057788e08482a468cc3bc00780Rusty Russell lg->mem_base = (void __user *)(long)args[0]; 1553c6b5bfa3cf3b4057788e08482a468cc3bc00780Rusty Russell lg->pfn_limit = args[1]; 156dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell 1574dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa /* This is the first cpu */ 158d0953d42c3445a120299fac9ad70e672d77898e9Glauber de Oliveira Costa err = lg_cpu_start(&lg->cpus[0], 0, args[3]); 1594dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa if (err) 1604dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa goto release_guest; 1614dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa 162dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* We need a complete page for the Guest registers: they are accessible 163dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * to the Guest and we can only grant it access to whole pages. */ 164d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell lg->regs_page = get_zeroed_page(GFP_KERNEL); 165d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (!lg->regs_page) { 166d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell err = -ENOMEM; 167d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell goto release_guest; 168d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } 169dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* We actually put the registers at the bottom of the page. */ 170d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell lg->regs = (void *)lg->regs_page + PAGE_SIZE - sizeof(*lg->regs); 171d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 172dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* Initialize the Guest's shadow page tables, using the toplevel 173dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * address the Launcher gave us. This allocates memory, so can 174dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * fail. */ 1753c6b5bfa3cf3b4057788e08482a468cc3bc00780Rusty Russell err = init_guest_pagetable(lg, args[2]); 176d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (err) 177d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell goto free_regs; 178d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 179dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* Now we initialize the Guest's registers, handing it the start 180dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * address. */ 181d612cde060a005c1effb13d0f665448a04ce5f67Jes Sorensen lguest_arch_setup_regs(lg, args[3]); 182dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell 183dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* The timer for lguest's clock needs initialization. */ 184d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell init_clockdev(lg); 185dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell 186dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* We keep a pointer to the Launcher task (ie. current task) for when 187dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * other Guests want to wake this one (inter-Guest I/O). */ 188d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell lg->tsk = current; 189dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* We need to keep a pointer to the Launcher's memory map, because if 190dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * the Launcher dies we need to clean it up. If we don't keep a 191dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * reference, it is destroyed before close() is called. */ 192d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell lg->mm = get_task_mm(lg->tsk); 193dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell 194dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* Initialize the queue for the waker to wait on */ 195d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell init_waitqueue_head(&lg->break_wq); 196dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell 197dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* We remember which CPU's pages this Guest used last, for optimization 198dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * when the same Guest runs on the same CPU twice. */ 199d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell lg->last_pages = NULL; 200dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell 201dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* We keep our "struct lguest" in the file's private_data. */ 202d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell file->private_data = lg; 203d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 204d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell mutex_unlock(&lguest_lock); 205d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 206dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* And because this is a write() call, we return the length used. */ 207d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return sizeof(args); 208d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 209d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russellfree_regs: 210d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell free_page(lg->regs_page); 211d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russellrelease_guest: 21243054412db5e5b3eda1eff6c2245ff4257560340Adrian Bunk kfree(lg); 213d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russellunlock: 214d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell mutex_unlock(&lguest_lock); 215d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return err; 216d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell} 217d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 218dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell/*L:010 The first operation the Launcher does must be a write. All writes 219e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell * start with an unsigned long number: for the first write this must be 220dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * LHREQ_INITIALIZE to set up the Guest. After that the Launcher can use 22115045275c32bf6d15d32c2eca8157be9c0ba6e45Rusty Russell * writes of other values to send interrupts. */ 222511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensenstatic ssize_t write(struct file *file, const char __user *in, 223d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell size_t size, loff_t *off) 224d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell{ 225dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* Once the guest is initialized, we hold the "struct lguest" in the 226dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * file private data. */ 227d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell struct lguest *lg = file->private_data; 228511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensen const unsigned long __user *input = (const unsigned long __user *)in; 229511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensen unsigned long req; 2307ea07a1500f05e06ebf0136763c781244f77a2a1Glauber de Oliveira Costa struct lg_cpu *cpu; 2317ea07a1500f05e06ebf0136763c781244f77a2a1Glauber de Oliveira Costa unsigned int cpu_id = *off; 232d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 233d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (get_user(req, input) != 0) 234d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return -EFAULT; 235511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensen input++; 236d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 237dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* If you haven't initialized, you must do that first. */ 2387ea07a1500f05e06ebf0136763c781244f77a2a1Glauber de Oliveira Costa if (req != LHREQ_INITIALIZE) { 2397ea07a1500f05e06ebf0136763c781244f77a2a1Glauber de Oliveira Costa if (!lg || (cpu_id >= lg->nr_cpus)) 2407ea07a1500f05e06ebf0136763c781244f77a2a1Glauber de Oliveira Costa return -EINVAL; 2417ea07a1500f05e06ebf0136763c781244f77a2a1Glauber de Oliveira Costa cpu = &lg->cpus[cpu_id]; 2427ea07a1500f05e06ebf0136763c781244f77a2a1Glauber de Oliveira Costa if (!cpu) 2437ea07a1500f05e06ebf0136763c781244f77a2a1Glauber de Oliveira Costa return -EINVAL; 2447ea07a1500f05e06ebf0136763c781244f77a2a1Glauber de Oliveira Costa } 245dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell 246dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* Once the Guest is dead, all you can do is read() why it died. */ 247d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (lg && lg->dead) 248d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return -ENOENT; 249d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 250d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell /* If you're not the task which owns the Guest, you can only break */ 251d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (lg && current != lg->tsk && req != LHREQ_BREAK) 252d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return -EPERM; 253d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 254d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell switch (req) { 255d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell case LHREQ_INITIALIZE: 256511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensen return initialize(file, input); 257d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell case LHREQ_IRQ: 258511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensen return user_send_irq(lg, input); 259d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell case LHREQ_BREAK: 260511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensen return break_guest_out(lg, input); 261d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell default: 262d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return -EINVAL; 263d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } 264d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell} 265d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 266dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell/*L:060 The final piece of interface code is the close() routine. It reverses 267dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * everything done in initialize(). This is usually called because the 268dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * Launcher exited. 269dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * 270dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * Note that the close routine returns 0 or a negative error number: it can't 271dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * really fail, but it can whine. I blame Sun for this wart, and K&R C for 272dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * letting them do it. :*/ 273d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russellstatic int close(struct inode *inode, struct file *file) 274d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell{ 275d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell struct lguest *lg = file->private_data; 276d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 277dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* If we never successfully initialized, there's nothing to clean up */ 278d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (!lg) 279d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return 0; 280d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 281dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* We need the big lock, to protect from inter-guest I/O and other 282dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * Launchers initializing guests. */ 283d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell mutex_lock(&lguest_lock); 284d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell /* Cancels the hrtimer set via LHCALL_SET_CLOCKEVENT. */ 285d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell hrtimer_cancel(&lg->hrt); 286dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* Free up the shadow page tables for the Guest. */ 287d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell free_guest_pagetable(lg); 288dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* Now all the memory cleanups are done, it's safe to release the 289dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * Launcher's memory management structure. */ 290d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell mmput(lg->mm); 291dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* If lg->dead doesn't contain an error code it will be NULL or a 292dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * kmalloc()ed string, either of which is ok to hand to kfree(). */ 293d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (!IS_ERR(lg->dead)) 294d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell kfree(lg->dead); 295dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* We can free up the register page we allocated. */ 296d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell free_page(lg->regs_page); 297dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* We clear the entire structure, which also marks it as free for the 298dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * next user. */ 299d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell memset(lg, 0, sizeof(*lg)); 300dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* Release lock and exit. */ 301d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell mutex_unlock(&lguest_lock); 302dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell 303d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return 0; 304d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell} 305d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 306dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell/*L:000 307dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * Welcome to our journey through the Launcher! 308dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * 309dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * The Launcher is the Host userspace program which sets up, runs and services 310dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * the Guest. In fact, many comments in the Drivers which refer to "the Host" 311dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * doing things are inaccurate: the Launcher does all the device handling for 312e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell * the Guest, but the Guest can't know that. 313dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * 314dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * Just to confuse you: to the Host kernel, the Launcher *is* the Guest and we 315dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * shall see more of that later. 316dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * 317dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * We begin our understanding with the Host kernel interface which the Launcher 318dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * uses: reading and writing a character device called /dev/lguest. All the 319dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * work happens in the read(), write() and close() routines: */ 320d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russellstatic struct file_operations lguest_fops = { 321d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell .owner = THIS_MODULE, 322d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell .release = close, 323d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell .write = write, 324d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell .read = read, 325d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell}; 326dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell 327dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell/* This is a textbook example of a "misc" character device. Populate a "struct 328dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * miscdevice" and register it with misc_register(). */ 329d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russellstatic struct miscdevice lguest_dev = { 330d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell .minor = MISC_DYNAMIC_MINOR, 331d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell .name = "lguest", 332d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell .fops = &lguest_fops, 333d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell}; 334d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 335d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russellint __init lguest_device_init(void) 336d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell{ 337d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return misc_register(&lguest_dev); 338d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell} 339d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 340d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russellvoid __exit lguest_device_remove(void) 341d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell{ 342d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell misc_deregister(&lguest_dev); 343d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell} 344