Skip to content

Commit f938d2c

Browse files
rustyrussellLinus Torvalds
authored andcommitted
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 <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent dfb6868 commit f938d2c

File tree

14 files changed

+218
-19
lines changed

14 files changed

+218
-19
lines changed

Documentation/lguest/extract

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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+

Documentation/lguest/lguest.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
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. :*/
38
#define _LARGEFILE64_SOURCE
49
#define _GNU_SOURCE
510
#include <stdio.h>

drivers/lguest/Makefile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,15 @@ obj-$(CONFIG_LGUEST_GUEST) += lguest.o lguest_asm.o lguest_bus.o
55
obj-$(CONFIG_LGUEST) += lg.o
66
lg-y := core.o hypercalls.o page_tables.o interrupts_and_traps.o \
77
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*'`

drivers/lguest/README

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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.

drivers/lguest/core.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
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. :*/
36
#include <linux/module.h>
47
#include <linux/stringify.h>
58
#include <linux/stddef.h>

drivers/lguest/hypercalls.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
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
38
49
This program is free software; you can redistribute it and/or modify
510
it under the terms of the GNU General Public License as published by

drivers/lguest/interrupts_and_traps.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
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. :*/
114
#include <linux/uaccess.h>
215
#include "lg.h"
316

drivers/lguest/io.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
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
37
*
48
* This program is free software; you can redistribute it and/or modify
59
* it under the terms of the GNU General Public License as published by

drivers/lguest/lguest.c

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,32 @@
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."
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.
318
*
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+
/*
430
* Copyright (C) 2006, Rusty Russell <[email protected]> IBM Corporation.
531
*
632
* This program is free software; you can redistribute it and/or modify

drivers/lguest/lguest_bus.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
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. :*/
14
#include <linux/init.h>
25
#include <linux/bootmem.h>
36
#include <linux/lguest_bus.h>

drivers/lguest/lguest_user.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
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. :*/
27
#include <linux/uaccess.h>
38
#include <linux/miscdevice.h>
49
#include <linux/fs.h>

drivers/lguest/page_tables.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
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.
39
* GPL v2 and any later version */
410
#include <linux/mm.h>
511
#include <linux/types.h>

drivers/lguest/segments.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
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. :*/
112
#include "lg.h"
213

314
static int desc_ok(const struct desc_struct *gdt)

drivers/lguest/switcher.S

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
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". :*/
28

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-
*/
89
#include <linux/linkage.h>
910
#include <asm/asm-offsets.h>
1011
#include "lg.h"

0 commit comments

Comments
 (0)