aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/lguest.h
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2007-07-26 13:41:02 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-26 14:35:17 -0400
commitb2b47c214f4e85ce3968120d42e8b18eccb4f4e3 (patch)
treef77d6898a769b8e0fcb552207e87f273bdc19f09 /include/linux/lguest.h
parentf938d2c892db0d80d144253d4a7b7083efdbedeb (diff)
lguest: documentation II: Guest
Documentation: The Guest 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>
Diffstat (limited to 'include/linux/lguest.h')
-rw-r--r--include/linux/lguest.h47
1 files changed, 38 insertions, 9 deletions
diff --git a/include/linux/lguest.h b/include/linux/lguest.h
index 500aace21ca7..e76c151c7129 100644
--- a/include/linux/lguest.h
+++ b/include/linux/lguest.h
@@ -27,18 +27,38 @@
27#define LG_CLOCK_MIN_DELTA 100UL 27#define LG_CLOCK_MIN_DELTA 100UL
28#define LG_CLOCK_MAX_DELTA ULONG_MAX 28#define LG_CLOCK_MAX_DELTA ULONG_MAX
29 29
30/*G:031 First, how does our Guest contact the Host to ask for privileged
31 * operations? There are two ways: the direct way is to make a "hypercall",
32 * to make requests of the Host Itself.
33 *
34 * Our hypercall mechanism uses the highest unused trap code (traps 32 and
35 * above are used by real hardware interrupts). Seventeen hypercalls are
36 * available: the hypercall number is put in the %eax register, and the
37 * arguments (when required) are placed in %edx, %ebx and %ecx. If a return
38 * value makes sense, it's returned in %eax.
39 *
40 * Grossly invalid calls result in Sudden Death at the hands of the vengeful
41 * Host, rather than returning failure. This reflects Winston Churchill's
42 * definition of a gentleman: "someone who is only rude intentionally". */
30#define LGUEST_TRAP_ENTRY 0x1F 43#define LGUEST_TRAP_ENTRY 0x1F
31 44
32static inline unsigned long 45static inline unsigned long
33hcall(unsigned long call, 46hcall(unsigned long call,
34 unsigned long arg1, unsigned long arg2, unsigned long arg3) 47 unsigned long arg1, unsigned long arg2, unsigned long arg3)
35{ 48{
49 /* "int" is the Intel instruction to trigger a trap. */
36 asm volatile("int $" __stringify(LGUEST_TRAP_ENTRY) 50 asm volatile("int $" __stringify(LGUEST_TRAP_ENTRY)
51 /* The call is in %eax (aka "a"), and can be replaced */
37 : "=a"(call) 52 : "=a"(call)
53 /* The other arguments are in %eax, %edx, %ebx & %ecx */
38 : "a"(call), "d"(arg1), "b"(arg2), "c"(arg3) 54 : "a"(call), "d"(arg1), "b"(arg2), "c"(arg3)
55 /* "memory" means this might write somewhere in memory.
56 * This isn't true for all calls, but it's safe to tell
57 * gcc that it might happen so it doesn't get clever. */
39 : "memory"); 58 : "memory");
40 return call; 59 return call;
41} 60}
61/*:*/
42 62
43void async_hcall(unsigned long call, 63void async_hcall(unsigned long call,
44 unsigned long arg1, unsigned long arg2, unsigned long arg3); 64 unsigned long arg1, unsigned long arg2, unsigned long arg3);
@@ -52,31 +72,40 @@ struct hcall_ring
52 u32 eax, edx, ebx, ecx; 72 u32 eax, edx, ebx, ecx;
53}; 73};
54 74
55/* All the good stuff happens here: guest registers it with LGUEST_INIT */ 75/*G:032 The second method of communicating with the Host is to via "struct
76 * lguest_data". The Guest's very first hypercall is to tell the Host where
77 * this is, and then the Guest and Host both publish information in it. :*/
56struct lguest_data 78struct lguest_data
57{ 79{
58/* Fields which change during running: */ 80 /* 512 == enabled (same as eflags in normal hardware). The Guest
59 /* 512 == enabled (same as eflags) */ 81 * changes interrupts so often that a hypercall is too slow. */
60 unsigned int irq_enabled; 82 unsigned int irq_enabled;
61 /* Interrupts blocked by guest. */ 83 /* Fine-grained interrupt disabling by the Guest */
62 DECLARE_BITMAP(blocked_interrupts, LGUEST_IRQS); 84 DECLARE_BITMAP(blocked_interrupts, LGUEST_IRQS);
63 85
64 /* Virtual address of page fault. */ 86 /* The Host writes the virtual address of the last page fault here,
87 * which saves the Guest a hypercall. CR2 is the native register where
88 * this address would normally be found. */
65 unsigned long cr2; 89 unsigned long cr2;
66 90
67 /* Async hypercall ring. 0xFF == done, 0 == pending. */ 91 /* Async hypercall ring. Instead of directly making hypercalls, we can
92 * place them in here for processing the next time the Host wants.
93 * This batching can be quite efficient. */
94
95 /* 0xFF == done (set by Host), 0 == pending (set by Guest). */
68 u8 hcall_status[LHCALL_RING_SIZE]; 96 u8 hcall_status[LHCALL_RING_SIZE];
97 /* The actual registers for the hypercalls. */
69 struct hcall_ring hcalls[LHCALL_RING_SIZE]; 98 struct hcall_ring hcalls[LHCALL_RING_SIZE];
70 99
71/* Fields initialized by the hypervisor at boot: */ 100/* Fields initialized by the Host at boot: */
72 /* Memory not to try to access */ 101 /* Memory not to try to access */
73 unsigned long reserve_mem; 102 unsigned long reserve_mem;
74 /* ID of this guest (used by network driver to set ethernet address) */ 103 /* ID of this Guest (used by network driver to set ethernet address) */
75 u16 guestid; 104 u16 guestid;
76 /* KHz for the TSC clock. */ 105 /* KHz for the TSC clock. */
77 u32 tsc_khz; 106 u32 tsc_khz;
78 107
79/* Fields initialized by the guest at boot: */ 108/* Fields initialized by the Guest at boot: */
80 /* Instruction range to suppress interrupts even if enabled */ 109 /* Instruction range to suppress interrupts even if enabled */
81 unsigned long noirq_start, noirq_end; 110 unsigned long noirq_start, noirq_end;
82}; 111};