lguest_user.c revision 74dbf719ed3c49687dab507967ebab9189e91ab0
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> 9ca94f2bdd1be626361fcfbd474d6b8823ed39f74Glauber de Oliveira Costa#include <linux/sched.h> 10d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell#include "lg.h" 11d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 12e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell/*L:055 When something happens, the Waker process needs a way to stop the 13e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell * kernel running the Guest and return to the Launcher. So the Waker writes 14e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell * LHREQ_BREAK and the value "1" to /dev/lguest to do this. Once the Launcher 15e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell * has done whatever needs attention, it writes LHREQ_BREAK and "0" to release 16e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell * the Waker. */ 1766686c2ab08feb721ca4d98285fba64acdf6017fGlauber de Oliveira Costastatic int break_guest_out(struct lg_cpu *cpu, const unsigned long __user*input) 18d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell{ 19d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell unsigned long on; 20d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 21e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell /* Fetch whether they're turning break on or off. */ 22d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (get_user(on, input) != 0) 23d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return -EFAULT; 24d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 25d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (on) { 2666686c2ab08feb721ca4d98285fba64acdf6017fGlauber de Oliveira Costa cpu->break_out = 1; 27e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell /* Pop it out of the Guest (may be running on different CPU) */ 2866686c2ab08feb721ca4d98285fba64acdf6017fGlauber de Oliveira Costa wake_up_process(cpu->tsk); 29d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell /* Wait for them to reset it */ 3066686c2ab08feb721ca4d98285fba64acdf6017fGlauber de Oliveira Costa return wait_event_interruptible(cpu->break_wq, !cpu->break_out); 31d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } else { 3266686c2ab08feb721ca4d98285fba64acdf6017fGlauber de Oliveira Costa cpu->break_out = 0; 3366686c2ab08feb721ca4d98285fba64acdf6017fGlauber de Oliveira Costa wake_up(&cpu->break_wq); 34d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return 0; 35d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } 36d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell} 37d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 38dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell/*L:050 Sending an interrupt is done by writing LHREQ_IRQ and an interrupt 39dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * number to /dev/lguest. */ 40177e449dc5bd4cf8dc48d66abee61ddf34b126b9Glauber de Oliveira Costastatic int user_send_irq(struct lg_cpu *cpu, const unsigned long __user *input) 41d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell{ 42511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensen unsigned long irq; 43d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 44d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (get_user(irq, input) != 0) 45d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return -EFAULT; 46d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (irq >= LGUEST_IRQS) 47d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return -EINVAL; 48dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* Next time the Guest runs, the core code will see if it can deliver 49dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * this interrupt. */ 50177e449dc5bd4cf8dc48d66abee61ddf34b126b9Glauber de Oliveira Costa set_bit(irq, cpu->irqs_pending); 51d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return 0; 52d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell} 53d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 54dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell/*L:040 Once our Guest is initialized, the Launcher makes it run by reading 55dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * from /dev/lguest. */ 56d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russellstatic ssize_t read(struct file *file, char __user *user, size_t size,loff_t*o) 57d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell{ 58d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell struct lguest *lg = file->private_data; 59d0953d42c3445a120299fac9ad70e672d77898e9Glauber de Oliveira Costa struct lg_cpu *cpu; 60d0953d42c3445a120299fac9ad70e672d77898e9Glauber de Oliveira Costa unsigned int cpu_id = *o; 61d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 62dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* You must write LHREQ_INITIALIZE first! */ 63d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (!lg) 64d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return -EINVAL; 65d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 66d0953d42c3445a120299fac9ad70e672d77898e9Glauber de Oliveira Costa /* Watch out for arbitrary vcpu indexes! */ 67d0953d42c3445a120299fac9ad70e672d77898e9Glauber de Oliveira Costa if (cpu_id >= lg->nr_cpus) 68d0953d42c3445a120299fac9ad70e672d77898e9Glauber de Oliveira Costa return -EINVAL; 69d0953d42c3445a120299fac9ad70e672d77898e9Glauber de Oliveira Costa 70d0953d42c3445a120299fac9ad70e672d77898e9Glauber de Oliveira Costa cpu = &lg->cpus[cpu_id]; 71d0953d42c3445a120299fac9ad70e672d77898e9Glauber de Oliveira Costa 72e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell /* If you're not the task which owns the Guest, go away. */ 7366686c2ab08feb721ca4d98285fba64acdf6017fGlauber de Oliveira Costa if (current != cpu->tsk) 74d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return -EPERM; 75d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 76a6bd8e13034dd7d60b6f14217096efa192d0adc1Rusty Russell /* If the Guest is already dead, we indicate why */ 77d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (lg->dead) { 78d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell size_t len; 79d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 80dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* lg->dead either contains an error code, or a string. */ 81d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (IS_ERR(lg->dead)) 82d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return PTR_ERR(lg->dead); 83d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 84dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* We can only return as much as the buffer they read with. */ 85d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell len = min(size, strlen(lg->dead)+1); 86d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (copy_to_user(user, lg->dead, len) != 0) 87d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return -EFAULT; 88d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return len; 89d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } 90d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 91a6bd8e13034dd7d60b6f14217096efa192d0adc1Rusty Russell /* If we returned from read() last time because the Guest sent I/O, 92dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * clear the flag. */ 935e232f4f428c4266ba5cdae9f23ba19a0913dcf9Glauber de Oliveira Costa if (cpu->pending_notify) 945e232f4f428c4266ba5cdae9f23ba19a0913dcf9Glauber de Oliveira Costa cpu->pending_notify = 0; 95d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 96dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* Run the Guest until something interesting happens. */ 97d0953d42c3445a120299fac9ad70e672d77898e9Glauber de Oliveira Costa return run_guest(cpu, (unsigned long __user *)user); 98d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell} 99d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 100a6bd8e13034dd7d60b6f14217096efa192d0adc1Rusty Russell/*L:025 This actually initializes a CPU. For the moment, a Guest is only 101a6bd8e13034dd7d60b6f14217096efa192d0adc1Rusty Russell * uniprocessor, so "id" is always 0. */ 1024dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costastatic int lg_cpu_start(struct lg_cpu *cpu, unsigned id, unsigned long start_ip) 1034dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa{ 104a6bd8e13034dd7d60b6f14217096efa192d0adc1Rusty Russell /* We have a limited number the number of CPUs in the lguest struct. */ 1054dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa if (id >= NR_CPUS) 1064dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa return -EINVAL; 1074dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa 108a6bd8e13034dd7d60b6f14217096efa192d0adc1Rusty Russell /* Set up this CPU's id, and pointer back to the lguest struct. */ 1094dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa cpu->id = id; 1104dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa cpu->lg = container_of((cpu - id), struct lguest, cpus[0]); 1114dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa cpu->lg->nr_cpus++; 112a6bd8e13034dd7d60b6f14217096efa192d0adc1Rusty Russell 113a6bd8e13034dd7d60b6f14217096efa192d0adc1Rusty Russell /* Each CPU has a timer it can set. */ 114ad8d8f3bc61ec712dd141e1029ae68c47fadc4a7Glauber de Oliveira Costa init_clockdev(cpu); 1154dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa 116a53a35a8b485b9c16b73e5177bddaa4321971199Glauber de Oliveira Costa /* We need a complete page for the Guest registers: they are accessible 117a53a35a8b485b9c16b73e5177bddaa4321971199Glauber de Oliveira Costa * to the Guest and we can only grant it access to whole pages. */ 118a53a35a8b485b9c16b73e5177bddaa4321971199Glauber de Oliveira Costa cpu->regs_page = get_zeroed_page(GFP_KERNEL); 119a53a35a8b485b9c16b73e5177bddaa4321971199Glauber de Oliveira Costa if (!cpu->regs_page) 120a53a35a8b485b9c16b73e5177bddaa4321971199Glauber de Oliveira Costa return -ENOMEM; 121a53a35a8b485b9c16b73e5177bddaa4321971199Glauber de Oliveira Costa 122a53a35a8b485b9c16b73e5177bddaa4321971199Glauber de Oliveira Costa /* We actually put the registers at the bottom of the page. */ 123a53a35a8b485b9c16b73e5177bddaa4321971199Glauber de Oliveira Costa cpu->regs = (void *)cpu->regs_page + PAGE_SIZE - sizeof(*cpu->regs); 124a53a35a8b485b9c16b73e5177bddaa4321971199Glauber de Oliveira Costa 125a53a35a8b485b9c16b73e5177bddaa4321971199Glauber de Oliveira Costa /* Now we initialize the Guest's registers, handing it the start 126a53a35a8b485b9c16b73e5177bddaa4321971199Glauber de Oliveira Costa * address. */ 127a53a35a8b485b9c16b73e5177bddaa4321971199Glauber de Oliveira Costa lguest_arch_setup_regs(cpu, start_ip); 128a53a35a8b485b9c16b73e5177bddaa4321971199Glauber de Oliveira Costa 129a6bd8e13034dd7d60b6f14217096efa192d0adc1Rusty Russell /* Initialize the queue for the Waker to wait on */ 13066686c2ab08feb721ca4d98285fba64acdf6017fGlauber de Oliveira Costa init_waitqueue_head(&cpu->break_wq); 13166686c2ab08feb721ca4d98285fba64acdf6017fGlauber de Oliveira Costa 13266686c2ab08feb721ca4d98285fba64acdf6017fGlauber de Oliveira Costa /* We keep a pointer to the Launcher task (ie. current task) for when 133a6bd8e13034dd7d60b6f14217096efa192d0adc1Rusty Russell * other Guests want to wake this one (eg. console input). */ 13466686c2ab08feb721ca4d98285fba64acdf6017fGlauber de Oliveira Costa cpu->tsk = current; 13566686c2ab08feb721ca4d98285fba64acdf6017fGlauber de Oliveira Costa 13666686c2ab08feb721ca4d98285fba64acdf6017fGlauber de Oliveira Costa /* We need to keep a pointer to the Launcher's memory map, because if 13766686c2ab08feb721ca4d98285fba64acdf6017fGlauber de Oliveira Costa * the Launcher dies we need to clean it up. If we don't keep a 13866686c2ab08feb721ca4d98285fba64acdf6017fGlauber de Oliveira Costa * reference, it is destroyed before close() is called. */ 13966686c2ab08feb721ca4d98285fba64acdf6017fGlauber de Oliveira Costa cpu->mm = get_task_mm(cpu->tsk); 14066686c2ab08feb721ca4d98285fba64acdf6017fGlauber de Oliveira Costa 141f34f8c5fea079065671163c37d98328cff31980bGlauber de Oliveira Costa /* We remember which CPU's pages this Guest used last, for optimization 142f34f8c5fea079065671163c37d98328cff31980bGlauber de Oliveira Costa * when the same Guest runs on the same CPU twice. */ 143f34f8c5fea079065671163c37d98328cff31980bGlauber de Oliveira Costa cpu->last_pages = NULL; 144f34f8c5fea079065671163c37d98328cff31980bGlauber de Oliveira Costa 145a6bd8e13034dd7d60b6f14217096efa192d0adc1Rusty Russell /* No error == success. */ 1464dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa return 0; 1474dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa} 1484dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa 14947436aa4ad054c1c7c8231618e86ebd9305308dcRusty Russell/*L:020 The initialization write supplies 4 pointer sized (32 or 64 bit) 150511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensen * values (in addition to the LHREQ_INITIALIZE value). These are: 151dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * 1523c6b5bfa3cf3b4057788e08482a468cc3bc00780Rusty Russell * base: The start of the Guest-physical memory inside the Launcher memory. 1533c6b5bfa3cf3b4057788e08482a468cc3bc00780Rusty Russell * 154dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * pfnlimit: The highest (Guest-physical) page number the Guest should be 155e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell * allowed to access. The Guest memory lives inside the Launcher, so it sets 156e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell * this to ensure the Guest can only reach its own memory. 157dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * 158dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * pgdir: The (Guest-physical) address of the top of the initial Guest 159dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * pagetables (which are set up by the Launcher). 160dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * 161dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * start: The first instruction to execute ("eip" in x86-speak). 162dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell */ 163511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensenstatic int initialize(struct file *file, const unsigned long __user *input) 164d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell{ 165dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* "struct lguest" contains everything we (the Host) know about a 166dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * Guest. */ 167d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell struct lguest *lg; 16848245cc0708d49d1d0566b9fa617ad6c5f4c6934Rusty Russell int err; 16947436aa4ad054c1c7c8231618e86ebd9305308dcRusty Russell unsigned long args[4]; 170d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 17148245cc0708d49d1d0566b9fa617ad6c5f4c6934Rusty Russell /* We grab the Big Lguest lock, which protects against multiple 17248245cc0708d49d1d0566b9fa617ad6c5f4c6934Rusty Russell * simultaneous initializations. */ 173d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell mutex_lock(&lguest_lock); 174dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* You can't initialize twice! Close the device and start again... */ 175d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (file->private_data) { 176d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell err = -EBUSY; 177d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell goto unlock; 178d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } 179d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 180d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (copy_from_user(args, input, sizeof(args)) != 0) { 181d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell err = -EFAULT; 182d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell goto unlock; 183d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } 184d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 18548245cc0708d49d1d0566b9fa617ad6c5f4c6934Rusty Russell lg = kzalloc(sizeof(*lg), GFP_KERNEL); 18648245cc0708d49d1d0566b9fa617ad6c5f4c6934Rusty Russell if (!lg) { 18748245cc0708d49d1d0566b9fa617ad6c5f4c6934Rusty Russell err = -ENOMEM; 188d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell goto unlock; 189d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } 190dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell 191dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* Populate the easy fields of our "struct lguest" */ 19274dbf719ed3c49687dab507967ebab9189e91ab0Al Viro lg->mem_base = (void __user *)args[0]; 1933c6b5bfa3cf3b4057788e08482a468cc3bc00780Rusty Russell lg->pfn_limit = args[1]; 194dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell 195a6bd8e13034dd7d60b6f14217096efa192d0adc1Rusty Russell /* This is the first cpu (cpu 0) and it will start booting at args[3] */ 196d0953d42c3445a120299fac9ad70e672d77898e9Glauber de Oliveira Costa err = lg_cpu_start(&lg->cpus[0], 0, args[3]); 1974dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa if (err) 1984dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa goto release_guest; 1994dcc53da49c2387078fe8ceb7a420d125e027fc6Glauber de Oliveira Costa 200dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* Initialize the Guest's shadow page tables, using the toplevel 201a6bd8e13034dd7d60b6f14217096efa192d0adc1Rusty Russell * address the Launcher gave us. This allocates memory, so can fail. */ 2023c6b5bfa3cf3b4057788e08482a468cc3bc00780Rusty Russell err = init_guest_pagetable(lg, args[2]); 203d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (err) 204d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell goto free_regs; 205d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 206dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* We keep our "struct lguest" in the file's private_data. */ 207d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell file->private_data = lg; 208d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 209d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell mutex_unlock(&lguest_lock); 210d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 211dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* And because this is a write() call, we return the length used. */ 212d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return sizeof(args); 213d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 214d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russellfree_regs: 215a53a35a8b485b9c16b73e5177bddaa4321971199Glauber de Oliveira Costa /* FIXME: This should be in free_vcpu */ 216a53a35a8b485b9c16b73e5177bddaa4321971199Glauber de Oliveira Costa free_page(lg->cpus[0].regs_page); 217d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russellrelease_guest: 21843054412db5e5b3eda1eff6c2245ff4257560340Adrian Bunk kfree(lg); 219d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russellunlock: 220d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell mutex_unlock(&lguest_lock); 221d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return err; 222d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell} 223d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 224dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell/*L:010 The first operation the Launcher does must be a write. All writes 225e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell * start with an unsigned long number: for the first write this must be 226dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * LHREQ_INITIALIZE to set up the Guest. After that the Launcher can use 227a6bd8e13034dd7d60b6f14217096efa192d0adc1Rusty Russell * writes of other values to send interrupts. 228a6bd8e13034dd7d60b6f14217096efa192d0adc1Rusty Russell * 229a6bd8e13034dd7d60b6f14217096efa192d0adc1Rusty Russell * Note that we overload the "offset" in the /dev/lguest file to indicate what 230a6bd8e13034dd7d60b6f14217096efa192d0adc1Rusty Russell * CPU number we're dealing with. Currently this is always 0, since we only 231a6bd8e13034dd7d60b6f14217096efa192d0adc1Rusty Russell * support uniprocessor Guests, but you can see the beginnings of SMP support 232a6bd8e13034dd7d60b6f14217096efa192d0adc1Rusty Russell * here. */ 233511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensenstatic ssize_t write(struct file *file, const char __user *in, 234d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell size_t size, loff_t *off) 235d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell{ 236a6bd8e13034dd7d60b6f14217096efa192d0adc1Rusty Russell /* Once the Guest is initialized, we hold the "struct lguest" in the 237dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * file private data. */ 238d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell struct lguest *lg = file->private_data; 239511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensen const unsigned long __user *input = (const unsigned long __user *)in; 240511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensen unsigned long req; 241177e449dc5bd4cf8dc48d66abee61ddf34b126b9Glauber de Oliveira Costa struct lg_cpu *uninitialized_var(cpu); 2427ea07a1500f05e06ebf0136763c781244f77a2a1Glauber de Oliveira Costa unsigned int cpu_id = *off; 243d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 244a6bd8e13034dd7d60b6f14217096efa192d0adc1Rusty Russell /* The first value tells us what this request is. */ 245d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (get_user(req, input) != 0) 246d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return -EFAULT; 247511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensen input++; 248d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 249dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* If you haven't initialized, you must do that first. */ 2507ea07a1500f05e06ebf0136763c781244f77a2a1Glauber de Oliveira Costa if (req != LHREQ_INITIALIZE) { 2517ea07a1500f05e06ebf0136763c781244f77a2a1Glauber de Oliveira Costa if (!lg || (cpu_id >= lg->nr_cpus)) 2527ea07a1500f05e06ebf0136763c781244f77a2a1Glauber de Oliveira Costa return -EINVAL; 2537ea07a1500f05e06ebf0136763c781244f77a2a1Glauber de Oliveira Costa cpu = &lg->cpus[cpu_id]; 2547ea07a1500f05e06ebf0136763c781244f77a2a1Glauber de Oliveira Costa if (!cpu) 2557ea07a1500f05e06ebf0136763c781244f77a2a1Glauber de Oliveira Costa return -EINVAL; 256dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell 257f73d1e6ca6985b43a1871467463cba632fbc624dEugene Teo /* Once the Guest is dead, you can only read() why it died. */ 258f73d1e6ca6985b43a1871467463cba632fbc624dEugene Teo if (lg->dead) 259f73d1e6ca6985b43a1871467463cba632fbc624dEugene Teo return -ENOENT; 260d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 261f73d1e6ca6985b43a1871467463cba632fbc624dEugene Teo /* If you're not the task which owns the Guest, all you can do 262f73d1e6ca6985b43a1871467463cba632fbc624dEugene Teo * is break the Launcher out of running the Guest. */ 263f73d1e6ca6985b43a1871467463cba632fbc624dEugene Teo if (current != cpu->tsk && req != LHREQ_BREAK) 264f73d1e6ca6985b43a1871467463cba632fbc624dEugene Teo return -EPERM; 265f73d1e6ca6985b43a1871467463cba632fbc624dEugene Teo } 266d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 267d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell switch (req) { 268d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell case LHREQ_INITIALIZE: 269511801dc31c095b2bfe3bf5c6a370dbe9b042a70Jes Sorensen return initialize(file, input); 270d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell case LHREQ_IRQ: 271177e449dc5bd4cf8dc48d66abee61ddf34b126b9Glauber de Oliveira Costa return user_send_irq(cpu, input); 272d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell case LHREQ_BREAK: 27366686c2ab08feb721ca4d98285fba64acdf6017fGlauber de Oliveira Costa return break_guest_out(cpu, input); 274d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell default: 275d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return -EINVAL; 276d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } 277d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell} 278d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 279dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell/*L:060 The final piece of interface code is the close() routine. It reverses 280dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * everything done in initialize(). This is usually called because the 281dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * Launcher exited. 282dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * 283dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * Note that the close routine returns 0 or a negative error number: it can't 284dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * really fail, but it can whine. I blame Sun for this wart, and K&R C for 285dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * letting them do it. :*/ 286d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russellstatic int close(struct inode *inode, struct file *file) 287d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell{ 288d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell struct lguest *lg = file->private_data; 289ad8d8f3bc61ec712dd141e1029ae68c47fadc4a7Glauber de Oliveira Costa unsigned int i; 290d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 291dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* If we never successfully initialized, there's nothing to clean up */ 292d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (!lg) 293d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return 0; 294d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 295dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* We need the big lock, to protect from inter-guest I/O and other 296dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * Launchers initializing guests. */ 297d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell mutex_lock(&lguest_lock); 29866686c2ab08feb721ca4d98285fba64acdf6017fGlauber de Oliveira Costa 29966686c2ab08feb721ca4d98285fba64acdf6017fGlauber de Oliveira Costa /* Free up the shadow page tables for the Guest. */ 30066686c2ab08feb721ca4d98285fba64acdf6017fGlauber de Oliveira Costa free_guest_pagetable(lg); 30166686c2ab08feb721ca4d98285fba64acdf6017fGlauber de Oliveira Costa 302a53a35a8b485b9c16b73e5177bddaa4321971199Glauber de Oliveira Costa for (i = 0; i < lg->nr_cpus; i++) { 303ad8d8f3bc61ec712dd141e1029ae68c47fadc4a7Glauber de Oliveira Costa /* Cancels the hrtimer set via LHCALL_SET_CLOCKEVENT. */ 304ad8d8f3bc61ec712dd141e1029ae68c47fadc4a7Glauber de Oliveira Costa hrtimer_cancel(&lg->cpus[i].hrt); 305a53a35a8b485b9c16b73e5177bddaa4321971199Glauber de Oliveira Costa /* We can free up the register page we allocated. */ 306a53a35a8b485b9c16b73e5177bddaa4321971199Glauber de Oliveira Costa free_page(lg->cpus[i].regs_page); 30766686c2ab08feb721ca4d98285fba64acdf6017fGlauber de Oliveira Costa /* Now all the memory cleanups are done, it's safe to release 30866686c2ab08feb721ca4d98285fba64acdf6017fGlauber de Oliveira Costa * the Launcher's memory management structure. */ 30966686c2ab08feb721ca4d98285fba64acdf6017fGlauber de Oliveira Costa mmput(lg->cpus[i].mm); 310a53a35a8b485b9c16b73e5177bddaa4321971199Glauber de Oliveira Costa } 311dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* If lg->dead doesn't contain an error code it will be NULL or a 312dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * kmalloc()ed string, either of which is ok to hand to kfree(). */ 313d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (!IS_ERR(lg->dead)) 314d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell kfree(lg->dead); 315dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* We clear the entire structure, which also marks it as free for the 316dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * next user. */ 317d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell memset(lg, 0, sizeof(*lg)); 318dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell /* Release lock and exit. */ 319d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell mutex_unlock(&lguest_lock); 320dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell 321d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return 0; 322d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell} 323d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 324dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell/*L:000 325dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * Welcome to our journey through the Launcher! 326dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * 327dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * The Launcher is the Host userspace program which sets up, runs and services 328dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * the Guest. In fact, many comments in the Drivers which refer to "the Host" 329dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * doing things are inaccurate: the Launcher does all the device handling for 330e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell * the Guest, but the Guest can't know that. 331dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * 332dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * Just to confuse you: to the Host kernel, the Launcher *is* the Guest and we 333dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * shall see more of that later. 334dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * 335dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * We begin our understanding with the Host kernel interface which the Launcher 336dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * uses: reading and writing a character device called /dev/lguest. All the 337dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * work happens in the read(), write() and close() routines: */ 338d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russellstatic struct file_operations lguest_fops = { 339d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell .owner = THIS_MODULE, 340d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell .release = close, 341d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell .write = write, 342d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell .read = read, 343d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell}; 344dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell 345dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell/* This is a textbook example of a "misc" character device. Populate a "struct 346dde797899ac17ebb812b7566044124d785e98dc7Rusty Russell * miscdevice" and register it with misc_register(). */ 347d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russellstatic struct miscdevice lguest_dev = { 348d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell .minor = MISC_DYNAMIC_MINOR, 349d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell .name = "lguest", 350d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell .fops = &lguest_fops, 351d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell}; 352d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 353d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russellint __init lguest_device_init(void) 354d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell{ 355d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return misc_register(&lguest_dev); 356d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell} 357d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 358d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russellvoid __exit lguest_device_remove(void) 359d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell{ 360d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell misc_deregister(&lguest_dev); 361d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell} 362