Loading Documentation/lguest/lguest.c +12 −0 Original line number Diff line number Diff line Loading @@ -1510,3 +1510,15 @@ int main(int argc, char *argv[]) /* Finally, run the Guest. This doesn't return. */ run_guest(lguest_fd, &device_list); } /*:*/ /*M:999 * Mastery is done: you now know everything I do. * * But surely you have seen code, features and bugs in your wanderings which * you now yearn to attack? That is the real game, and I look forward to you * patching and forking lguest into the Your-Name-Here-visor. * * Farewell, and good coding! * Rusty Russell. */ drivers/char/hvc_lguest.c +3 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,9 @@ * functions. :*/ /*M:002 The console can be flooded: while the Guest is processing input the * Host can send more. Buffering in the Host could alleviate this, but it is a * difficult problem in general. :*/ /* Copyright (C) 2006 Rusty Russell, IBM Corporation * * This program is free software; you can redistribute it and/or modify Loading drivers/lguest/interrupts_and_traps.c +14 −0 Original line number Diff line number Diff line Loading @@ -231,6 +231,20 @@ static int direct_trap(const struct lguest *lg, * go direct, of course 8) */ return idt_type(trap->a, trap->b) == 0xF; } /*:*/ /*M:005 The Guest has the ability to turn its interrupt gates into trap gates, * if it is careful. The Host will let trap gates can go directly to the * Guest, but the Guest needs the interrupts atomically disabled for an * interrupt gate. It can do this by pointing the trap gate at instructions * within noirq_start and noirq_end, where it can safely disable interrupts. */ /*M:006 The Guests do not use the sysenter (fast system call) instruction, * because it's hardcoded to enter privilege level 0 and so can't go direct. * It's about twice as fast as the older "int 0x80" system call, so it might * still be worthwhile to handle it in the Switcher and lcall down to the * Guest. The sysenter semantics are hairy tho: search for that keyword in * entry.S :*/ /*H:260 When we make traps go directly into the Guest, we need to make sure * the kernel stack is valid (ie. mapped in the page tables). Otherwise, the Loading drivers/lguest/io.c +10 −0 Original line number Diff line number Diff line Loading @@ -553,6 +553,16 @@ void release_all_dma(struct lguest *lg) up_read(&lg->mm->mmap_sem); } /*M:007 We only return a single DMA buffer to the Launcher, but it would be * more efficient to return a pointer to the entire array of DMA buffers, which * it can cache and choose one whenever it wants. * * Currently the Launcher uses a write to /dev/lguest, and the return value is * the address of the DMA structure with the interrupt number placed in * dma->used_len. If we wanted to return the entire array, we need to return * the address, array size and interrupt number: this seems to require an * ioctl(). :*/ /*L:320 This routine looks for a DMA buffer registered by the Guest on the * given key (using the BIND_DMA hypercall). */ unsigned long get_dma_buffer(struct lguest *lg, Loading drivers/lguest/lguest.c +8 −0 Original line number Diff line number Diff line Loading @@ -250,6 +250,14 @@ static void irq_enable(void) { lguest_data.irq_enabled = X86_EFLAGS_IF; } /*:*/ /*M:003 Note that we don't check for outstanding interrupts when we re-enable * them (or when we unmask an interrupt). This seems to work for the moment, * since interrupts are rare and we'll just get the interrupt on the next timer * tick, but when we turn on CONFIG_NO_HZ, we should revisit this. One way * would be to put the "irq_enabled" field in a page by itself, and have the * Host write-protect it when an interrupt comes in when irqs are disabled. * There will then be a page fault as soon as interrupts are re-enabled. :*/ /*G:034 * The Interrupt Descriptor Table (IDT). Loading Loading
Documentation/lguest/lguest.c +12 −0 Original line number Diff line number Diff line Loading @@ -1510,3 +1510,15 @@ int main(int argc, char *argv[]) /* Finally, run the Guest. This doesn't return. */ run_guest(lguest_fd, &device_list); } /*:*/ /*M:999 * Mastery is done: you now know everything I do. * * But surely you have seen code, features and bugs in your wanderings which * you now yearn to attack? That is the real game, and I look forward to you * patching and forking lguest into the Your-Name-Here-visor. * * Farewell, and good coding! * Rusty Russell. */
drivers/char/hvc_lguest.c +3 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,9 @@ * functions. :*/ /*M:002 The console can be flooded: while the Guest is processing input the * Host can send more. Buffering in the Host could alleviate this, but it is a * difficult problem in general. :*/ /* Copyright (C) 2006 Rusty Russell, IBM Corporation * * This program is free software; you can redistribute it and/or modify Loading
drivers/lguest/interrupts_and_traps.c +14 −0 Original line number Diff line number Diff line Loading @@ -231,6 +231,20 @@ static int direct_trap(const struct lguest *lg, * go direct, of course 8) */ return idt_type(trap->a, trap->b) == 0xF; } /*:*/ /*M:005 The Guest has the ability to turn its interrupt gates into trap gates, * if it is careful. The Host will let trap gates can go directly to the * Guest, but the Guest needs the interrupts atomically disabled for an * interrupt gate. It can do this by pointing the trap gate at instructions * within noirq_start and noirq_end, where it can safely disable interrupts. */ /*M:006 The Guests do not use the sysenter (fast system call) instruction, * because it's hardcoded to enter privilege level 0 and so can't go direct. * It's about twice as fast as the older "int 0x80" system call, so it might * still be worthwhile to handle it in the Switcher and lcall down to the * Guest. The sysenter semantics are hairy tho: search for that keyword in * entry.S :*/ /*H:260 When we make traps go directly into the Guest, we need to make sure * the kernel stack is valid (ie. mapped in the page tables). Otherwise, the Loading
drivers/lguest/io.c +10 −0 Original line number Diff line number Diff line Loading @@ -553,6 +553,16 @@ void release_all_dma(struct lguest *lg) up_read(&lg->mm->mmap_sem); } /*M:007 We only return a single DMA buffer to the Launcher, but it would be * more efficient to return a pointer to the entire array of DMA buffers, which * it can cache and choose one whenever it wants. * * Currently the Launcher uses a write to /dev/lguest, and the return value is * the address of the DMA structure with the interrupt number placed in * dma->used_len. If we wanted to return the entire array, we need to return * the address, array size and interrupt number: this seems to require an * ioctl(). :*/ /*L:320 This routine looks for a DMA buffer registered by the Guest on the * given key (using the BIND_DMA hypercall). */ unsigned long get_dma_buffer(struct lguest *lg, Loading
drivers/lguest/lguest.c +8 −0 Original line number Diff line number Diff line Loading @@ -250,6 +250,14 @@ static void irq_enable(void) { lguest_data.irq_enabled = X86_EFLAGS_IF; } /*:*/ /*M:003 Note that we don't check for outstanding interrupts when we re-enable * them (or when we unmask an interrupt). This seems to work for the moment, * since interrupts are rare and we'll just get the interrupt on the next timer * tick, but when we turn on CONFIG_NO_HZ, we should revisit this. One way * would be to put the "irq_enabled" field in a page by itself, and have the * Host write-protect it when an interrupt comes in when irqs are disabled. * There will then be a page fault as soon as interrupts are re-enabled. :*/ /*G:034 * The Interrupt Descriptor Table (IDT). Loading