Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

lguest: documentation I: Preparation

The netfilter code had very good documentation: the Netfilter Hacking HOWTO.
Noone ever read it.

So this time I'm trying something different, using a bit of Knuthiness.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Rusty Russell and committed by
Linus Torvalds
f938d2c8 dfb68689

+218 -19
+58
Documentation/lguest/extract
··· 1 + #! /bin/sh 2 + 3 + set -e 4 + 5 + PREFIX=$1 6 + shift 7 + 8 + trap 'rm -r $TMPDIR' 0 9 + TMPDIR=`mktemp -d` 10 + 11 + exec 3>/dev/null 12 + for f; do 13 + while IFS=" 14 + " read -r LINE; do 15 + case "$LINE" in 16 + *$PREFIX:[0-9]*:\**) 17 + NUM=`echo "$LINE" | sed "s/.*$PREFIX:\([0-9]*\).*/\1/"` 18 + if [ -f $TMPDIR/$NUM ]; then 19 + echo "$TMPDIR/$NUM already exits prior to $f" 20 + exit 1 21 + fi 22 + exec 3>>$TMPDIR/$NUM 23 + echo $f | sed 's,\.\./,,g' > $TMPDIR/.$NUM 24 + /bin/echo "$LINE" | sed -e "s/$PREFIX:[0-9]*//" -e "s/:\*/*/" >&3 25 + ;; 26 + *$PREFIX:[0-9]*) 27 + NUM=`echo "$LINE" | sed "s/.*$PREFIX:\([0-9]*\).*/\1/"` 28 + if [ -f $TMPDIR/$NUM ]; then 29 + echo "$TMPDIR/$NUM already exits prior to $f" 30 + exit 1 31 + fi 32 + exec 3>>$TMPDIR/$NUM 33 + echo $f | sed 's,\.\./,,g' > $TMPDIR/.$NUM 34 + /bin/echo "$LINE" | sed "s/$PREFIX:[0-9]*//" >&3 35 + ;; 36 + *:\**) 37 + /bin/echo "$LINE" | sed -e "s/:\*/*/" -e "s,/\*\*/,," >&3 38 + echo >&3 39 + exec 3>/dev/null 40 + ;; 41 + *) 42 + /bin/echo "$LINE" >&3 43 + ;; 44 + esac 45 + done < $f 46 + echo >&3 47 + exec 3>/dev/null 48 + done 49 + 50 + LASTFILE="" 51 + for f in $TMPDIR/*; do 52 + if [ "$LASTFILE" != $(cat $TMPDIR/.$(basename $f) ) ]; then 53 + LASTFILE=$(cat $TMPDIR/.$(basename $f) ) 54 + echo "[ $LASTFILE ]" 55 + fi 56 + cat $f 57 + done 58 +
+7 -2
Documentation/lguest/lguest.c
··· 1 - /* Simple program to layout "physical" memory for new lguest guest. 2 - * Linked high to avoid likely physical memory. */ 1 + /*P:100 This is the Launcher code, a simple program which lays out the 2 + * "physical" memory for the new Guest by mapping the kernel image and the 3 + * virtual devices, then reads repeatedly from /dev/lguest to run the Guest. 4 + * 5 + * The only trick: the Makefile links it at a high address so it will be clear 6 + * of the guest memory region. It means that each Guest cannot have more than 7 + * about 2.5G of memory on a normally configured Host. :*/ 3 8 #define _LARGEFILE64_SOURCE 4 9 #define _GNU_SOURCE 5 10 #include <stdio.h>
+12
drivers/lguest/Makefile
··· 5 5 obj-$(CONFIG_LGUEST) += lg.o 6 6 lg-y := core.o hypercalls.o page_tables.o interrupts_and_traps.o \ 7 7 segments.o io.o lguest_user.o switcher.o 8 + 9 + Preparation Preparation!: PREFIX=P 10 + Guest: PREFIX=G 11 + Drivers: PREFIX=D 12 + Launcher: PREFIX=L 13 + Host: PREFIX=H 14 + Switcher: PREFIX=S 15 + Mastery: PREFIX=M 16 + Beer: 17 + @for f in Preparation Guest Drivers Launcher Host Switcher Mastery; do echo "{==- $$f -==}"; make -s $$f; done; echo "{==-==}" 18 + Preparation Preparation! Guest Drivers Launcher Host Switcher Mastery: 19 + @sh ../../Documentation/lguest/extract $(PREFIX) `find ../../* -name '*.[chS]' -wholename '*lguest*'`
+47
drivers/lguest/README
··· 1 + Welcome, friend reader, to lguest. 2 + 3 + Lguest is an adventure, with you, the reader, as Hero. I can't think of many 4 + 5000-line projects which offer both such capability and glimpses of future 5 + potential; it is an exciting time to be delving into the source! 6 + 7 + But be warned; this is an arduous journey of several hours or more! And as we 8 + know, all true Heroes are driven by a Noble Goal. Thus I offer a Beer (or 9 + equivalent) to anyone I meet who has completed this documentation. 10 + 11 + So get comfortable and keep your wits about you (both quick and humorous). 12 + Along your way to the Noble Goal, you will also gain masterly insight into 13 + lguest, and hypervisors and x86 virtualization in general. 14 + 15 + Our Quest is in seven parts: (best read with C highlighting turned on) 16 + 17 + I) Preparation 18 + - In which our potential hero is flown quickly over the landscape for a 19 + taste of its scope. Suitable for the armchair coders and other such 20 + persons of faint constitution. 21 + 22 + II) Guest 23 + - Where we encounter the first tantalising wisps of code, and come to 24 + understand the details of the life of a Guest kernel. 25 + 26 + III) Drivers 27 + - Whereby the Guest finds its voice and become useful, and our 28 + understanding of the Guest is completed. 29 + 30 + IV) Launcher 31 + - Where we trace back to the creation of the Guest, and thus begin our 32 + understanding of the Host. 33 + 34 + V) Host 35 + - Where we master the Host code, through a long and tortuous journey. 36 + Indeed, it is here that our hero is tested in the Bit of Despair. 37 + 38 + VI) Switcher 39 + - Where our understanding of the intertwined nature of Guests and Hosts 40 + is completed. 41 + 42 + VII) Mastery 43 + - Where our fully fledged hero grapples with the Great Question: 44 + "What next?" 45 + 46 + make Preparation! 47 + Rusty Russell.
+5 -2
drivers/lguest/core.c
··· 1 - /* World's simplest hypervisor, to test paravirt_ops and show 2 - * unbelievers that virtualization is the future. Plus, it's fun! */ 1 + /*P:400 This contains run_guest() which actually calls into the Host<->Guest 2 + * Switcher and analyzes the return, such as determining if the Guest wants the 3 + * Host to do something. This file also contains useful helper routines, and a 4 + * couple of non-obvious setup and teardown pieces which were implemented after 5 + * days of debugging pain. :*/ 3 6 #include <linux/module.h> 4 7 #include <linux/stringify.h> 5 8 #include <linux/stddef.h>
+7 -2
drivers/lguest/hypercalls.c
··· 1 - /* Actual hypercalls, which allow guests to actually do something. 2 - Copyright (C) 2006 Rusty Russell IBM Corporation 1 + /*P:500 Just as userspace programs request kernel operations through a system 2 + * call, the Guest requests Host operations through a "hypercall". You might 3 + * notice this nomenclature doesn't really follow any logic, but the name has 4 + * been around for long enough that we're stuck with it. As you'd expect, this 5 + * code is basically a one big switch statement. :*/ 6 + 7 + /* Copyright (C) 2006 Rusty Russell IBM Corporation 3 8 4 9 This program is free software; you can redistribute it and/or modify 5 10 it under the terms of the GNU General Public License as published by
+13
drivers/lguest/interrupts_and_traps.c
··· 1 + /*P:800 Interrupts (traps) are complicated enough to earn their own file. 2 + * There are three classes of interrupts: 3 + * 4 + * 1) Real hardware interrupts which occur while we're running the Guest, 5 + * 2) Interrupts for virtual devices attached to the Guest, and 6 + * 3) Traps and faults from the Guest. 7 + * 8 + * Real hardware interrupts must be delivered to the Host, not the Guest. 9 + * Virtual interrupts must be delivered to the Guest, but we make them look 10 + * just like real hardware would deliver them. Traps from the Guest can be set 11 + * up to go directly back into the Guest, but sometimes the Host wants to see 12 + * them first, so we also have a way of "reflecting" them into the Guest as if 13 + * they had been delivered to it directly. :*/ 1 14 #include <linux/uaccess.h> 2 15 #include "lg.h" 3 16
+6 -2
drivers/lguest/io.c
··· 1 - /* Simple I/O model for guests, based on shared memory. 2 - * Copyright (C) 2006 Rusty Russell IBM Corporation 1 + /*P:300 The I/O mechanism in lguest is simple yet flexible, allowing the Guest 2 + * to talk to the Launcher or directly to another Guest. It uses familiar 3 + * concepts of DMA and interrupts, plus some neat code stolen from 4 + * futexes... :*/ 5 + 6 + /* Copyright (C) 2006 Rusty Russell IBM Corporation 3 7 * 4 8 * This program is free software; you can redistribute it and/or modify 5 9 * it under the terms of the GNU General Public License as published by
+28 -2
drivers/lguest/lguest.c
··· 1 - /* 2 - * Lguest specific paravirt-ops implementation 1 + /*P:010 2 + * A hypervisor allows multiple Operating Systems to run on a single machine. 3 + * To quote David Wheeler: "Any problem in computer science can be solved with 4 + * another layer of indirection." 3 5 * 6 + * We keep things simple in two ways. First, we start with a normal Linux 7 + * kernel and insert a module (lg.ko) which allows us to run other Linux 8 + * kernels the same way we'd run processes. We call the first kernel the Host, 9 + * and the others the Guests. The program which sets up and configures Guests 10 + * (such as the example in Documentation/lguest/lguest.c) is called the 11 + * Launcher. 12 + * 13 + * Secondly, we only run specially modified Guests, not normal kernels. When 14 + * you set CONFIG_LGUEST to 'y' or 'm', this automatically sets 15 + * CONFIG_LGUEST_GUEST=y, which compiles this file into the kernel so it knows 16 + * how to be a Guest. This means that you can use the same kernel you boot 17 + * normally (ie. as a Host) as a Guest. 18 + * 19 + * These Guests know that they cannot do privileged operations, such as disable 20 + * interrupts, and that they have to ask the Host to do such things explicitly. 21 + * This file consists of all the replacements for such low-level native 22 + * hardware operations: these special Guest versions call the Host. 23 + * 24 + * So how does the kernel know it's a Guest? The Guest starts at a special 25 + * entry point marked with a magic string, which sets up a few things then 26 + * calls here. We replace the native functions in "struct paravirt_ops" 27 + * with our Guest versions, then boot like normal. :*/ 28 + 29 + /* 4 30 * Copyright (C) 2006, Rusty Russell <rusty@rustcorp.com.au> IBM Corporation. 5 31 * 6 32 * This program is free software; you can redistribute it and/or modify
+3
drivers/lguest/lguest_bus.c
··· 1 + /*P:050 Lguest guests use a very simple bus for devices. It's a simple array 2 + * of device descriptors contained just above the top of normal memory. The 3 + * lguest bus is 80% tedious boilerplate code. :*/ 1 4 #include <linux/init.h> 2 5 #include <linux/bootmem.h> 3 6 #include <linux/lguest_bus.h>
+6 -1
drivers/lguest/lguest_user.c
··· 1 - /* Userspace control of the guest, via /dev/lguest. */ 1 + /*P:200 This contains all the /dev/lguest code, whereby the userspace launcher 2 + * controls and communicates with the Guest. For example, the first write will 3 + * tell us the memory size, pagetable, entry point and kernel address offset. 4 + * A read will run the Guest until a signal is pending (-EINTR), or the Guest 5 + * does a DMA out to the Launcher. Writes are also used to get a DMA buffer 6 + * registered by the Guest and to send the Guest an interrupt. :*/ 2 7 #include <linux/uaccess.h> 3 8 #include <linux/miscdevice.h> 4 9 #include <linux/fs.h>
+8 -2
drivers/lguest/page_tables.c
··· 1 - /* Shadow page table operations. 2 - * Copyright (C) Rusty Russell IBM Corporation 2006. 1 + /*P:700 The pagetable code, on the other hand, still shows the scars of 2 + * previous encounters. It's functional, and as neat as it can be in the 3 + * circumstances, but be wary, for these things are subtle and break easily. 4 + * The Guest provides a virtual to physical mapping, but we can neither trust 5 + * it nor use it: we verify and convert it here to point the hardware to the 6 + * actual Guest pages when running the Guest. :*/ 7 + 8 + /* Copyright (C) Rusty Russell IBM Corporation 2006. 3 9 * GPL v2 and any later version */ 4 10 #include <linux/mm.h> 5 11 #include <linux/types.h>
+11
drivers/lguest/segments.c
··· 1 + /*P:600 The x86 architecture has segments, which involve a table of descriptors 2 + * which can be used to do funky things with virtual address interpretation. 3 + * We originally used to use segments so the Guest couldn't alter the 4 + * Guest<->Host Switcher, and then we had to trim Guest segments, and restore 5 + * for userspace per-thread segments, but trim again for on userspace->kernel 6 + * transitions... This nightmarish creation was contained within this file, 7 + * where we knew not to tread without heavy armament and a change of underwear. 8 + * 9 + * In these modern times, the segment handling code consists of simple sanity 10 + * checks, and the worst you'll experience reading this code is butterfly-rash 11 + * from frolicking through its parklike serenity. :*/ 1 12 #include "lg.h" 2 13 3 14 static int desc_ok(const struct desc_struct *gdt)
+7 -6
drivers/lguest/switcher.S
··· 1 - /* This code sits at 0xFFC00000 to do the low-level guest<->host switch. 1 + /*P:900 This is the Switcher: code which sits at 0xFFC00000 to do the low-level 2 + * Guest<->Host switch. It is as simple as it can be made, but it's naturally 3 + * very specific to x86. 4 + * 5 + * You have now completed Preparation. If this has whet your appetite; if you 6 + * are feeling invigorated and refreshed then the next, more challenging stage 7 + * can be found in "make Guest". :*/ 2 8 3 - There is are two pages above us for this CPU (struct lguest_pages). 4 - The second page (struct lguest_ro_state) becomes read-only after the 5 - context switch. The first page (the stack for traps) remains writable, 6 - but while we're in here, the guest cannot be running. 7 - */ 8 9 #include <linux/linkage.h> 9 10 #include <asm/asm-offsets.h> 10 11 #include "lg.h"