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