aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/lguest/hypercalls.c
diff options
context:
space:
mode:
authorGlauber de Oliveira Costa <gcosta@redhat.com>2008-01-07 08:05:27 -0500
committerRusty Russell <rusty@rustcorp.com.au>2008-01-30 06:50:08 -0500
commit73044f05a4ac65f2df42753e9566444b9d2a660f (patch)
tree80a3e1d1bda31a769554a8c51f8c189ccec0b9f8 /drivers/lguest/hypercalls.c
parent7ea07a1500f05e06ebf0136763c781244f77a2a1 (diff)
lguest: make hypercalls use the vcpu struct
this patch changes do_hcall() and do_async_hcall() interfaces (and obviously their callers) to get a vcpu struct. Again, a vcpu services the hypercall, not the whole guest Signed-off-by: Glauber de Oliveira Costa <gcosta@redhat.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers/lguest/hypercalls.c')
-rw-r--r--drivers/lguest/hypercalls.c42
1 files changed, 23 insertions, 19 deletions
diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index 05fad6fa8049..7827671b2234 100644
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -29,8 +29,10 @@
29 29
30/*H:120 This is the core hypercall routine: where the Guest gets what it wants. 30/*H:120 This is the core hypercall routine: where the Guest gets what it wants.
31 * Or gets killed. Or, in the case of LHCALL_CRASH, both. */ 31 * Or gets killed. Or, in the case of LHCALL_CRASH, both. */
32static void do_hcall(struct lguest *lg, struct hcall_args *args) 32static void do_hcall(struct lg_cpu *cpu, struct hcall_args *args)
33{ 33{
34 struct lguest *lg = cpu->lg;
35
34 switch (args->arg0) { 36 switch (args->arg0) {
35 case LHCALL_FLUSH_ASYNC: 37 case LHCALL_FLUSH_ASYNC:
36 /* This call does nothing, except by breaking out of the Guest 38 /* This call does nothing, except by breaking out of the Guest
@@ -93,7 +95,7 @@ static void do_hcall(struct lguest *lg, struct hcall_args *args)
93 break; 95 break;
94 default: 96 default:
95 /* It should be an architecture-specific hypercall. */ 97 /* It should be an architecture-specific hypercall. */
96 if (lguest_arch_do_hcall(lg, args)) 98 if (lguest_arch_do_hcall(cpu, args))
97 kill_guest(lg, "Bad hypercall %li\n", args->arg0); 99 kill_guest(lg, "Bad hypercall %li\n", args->arg0);
98 } 100 }
99} 101}
@@ -106,10 +108,11 @@ static void do_hcall(struct lguest *lg, struct hcall_args *args)
106 * Guest put them in the ring, but we also promise the Guest that they will 108 * Guest put them in the ring, but we also promise the Guest that they will
107 * happen before any normal hypercall (which is why we check this before 109 * happen before any normal hypercall (which is why we check this before
108 * checking for a normal hcall). */ 110 * checking for a normal hcall). */
109static void do_async_hcalls(struct lguest *lg) 111static void do_async_hcalls(struct lg_cpu *cpu)
110{ 112{
111 unsigned int i; 113 unsigned int i;
112 u8 st[LHCALL_RING_SIZE]; 114 u8 st[LHCALL_RING_SIZE];
115 struct lguest *lg = cpu->lg;
113 116
114 /* For simplicity, we copy the entire call status array in at once. */ 117 /* For simplicity, we copy the entire call status array in at once. */
115 if (copy_from_user(&st, &lg->lguest_data->hcall_status, sizeof(st))) 118 if (copy_from_user(&st, &lg->lguest_data->hcall_status, sizeof(st)))
@@ -121,7 +124,7 @@ static void do_async_hcalls(struct lguest *lg)
121 /* We remember where we were up to from last time. This makes 124 /* We remember where we were up to from last time. This makes
122 * sure that the hypercalls are done in the order the Guest 125 * sure that the hypercalls are done in the order the Guest
123 * places them in the ring. */ 126 * places them in the ring. */
124 unsigned int n = lg->next_hcall; 127 unsigned int n = cpu->next_hcall;
125 128
126 /* 0xFF means there's no call here (yet). */ 129 /* 0xFF means there's no call here (yet). */
127 if (st[n] == 0xFF) 130 if (st[n] == 0xFF)
@@ -129,8 +132,8 @@ static void do_async_hcalls(struct lguest *lg)
129 132
130 /* OK, we have hypercall. Increment the "next_hcall" cursor, 133 /* OK, we have hypercall. Increment the "next_hcall" cursor,
131 * and wrap back to 0 if we reach the end. */ 134 * and wrap back to 0 if we reach the end. */
132 if (++lg->next_hcall == LHCALL_RING_SIZE) 135 if (++cpu->next_hcall == LHCALL_RING_SIZE)
133 lg->next_hcall = 0; 136 cpu->next_hcall = 0;
134 137
135 /* Copy the hypercall arguments into a local copy of 138 /* Copy the hypercall arguments into a local copy of
136 * the hcall_args struct. */ 139 * the hcall_args struct. */
@@ -141,7 +144,7 @@ static void do_async_hcalls(struct lguest *lg)
141 } 144 }
142 145
143 /* Do the hypercall, same as a normal one. */ 146 /* Do the hypercall, same as a normal one. */
144 do_hcall(lg, &args); 147 do_hcall(cpu, &args);
145 148
146 /* Mark the hypercall done. */ 149 /* Mark the hypercall done. */
147 if (put_user(0xFF, &lg->lguest_data->hcall_status[n])) { 150 if (put_user(0xFF, &lg->lguest_data->hcall_status[n])) {
@@ -158,16 +161,17 @@ static void do_async_hcalls(struct lguest *lg)
158 161
159/* Last of all, we look at what happens first of all. The very first time the 162/* Last of all, we look at what happens first of all. The very first time the
160 * Guest makes a hypercall, we end up here to set things up: */ 163 * Guest makes a hypercall, we end up here to set things up: */
161static void initialize(struct lguest *lg) 164static void initialize(struct lg_cpu *cpu)
162{ 165{
166 struct lguest *lg = cpu->lg;
163 /* You can't do anything until you're initialized. The Guest knows the 167 /* You can't do anything until you're initialized. The Guest knows the
164 * rules, so we're unforgiving here. */ 168 * rules, so we're unforgiving here. */
165 if (lg->hcall->arg0 != LHCALL_LGUEST_INIT) { 169 if (cpu->hcall->arg0 != LHCALL_LGUEST_INIT) {
166 kill_guest(lg, "hypercall %li before INIT", lg->hcall->arg0); 170 kill_guest(lg, "hypercall %li before INIT", cpu->hcall->arg0);
167 return; 171 return;
168 } 172 }
169 173
170 if (lguest_arch_init_hypercalls(lg)) 174 if (lguest_arch_init_hypercalls(cpu))
171 kill_guest(lg, "bad guest page %p", lg->lguest_data); 175 kill_guest(lg, "bad guest page %p", lg->lguest_data);
172 176
173 /* The Guest tells us where we're not to deliver interrupts by putting 177 /* The Guest tells us where we're not to deliver interrupts by putting
@@ -196,27 +200,27 @@ static void initialize(struct lguest *lg)
196 * Remember from the Guest, hypercalls come in two flavors: normal and 200 * Remember from the Guest, hypercalls come in two flavors: normal and
197 * asynchronous. This file handles both of types. 201 * asynchronous. This file handles both of types.
198 */ 202 */
199void do_hypercalls(struct lguest *lg) 203void do_hypercalls(struct lg_cpu *cpu)
200{ 204{
201 /* Not initialized yet? This hypercall must do it. */ 205 /* Not initialized yet? This hypercall must do it. */
202 if (unlikely(!lg->lguest_data)) { 206 if (unlikely(!cpu->lg->lguest_data)) {
203 /* Set up the "struct lguest_data" */ 207 /* Set up the "struct lguest_data" */
204 initialize(lg); 208 initialize(cpu);
205 /* Hcall is done. */ 209 /* Hcall is done. */
206 lg->hcall = NULL; 210 cpu->hcall = NULL;
207 return; 211 return;
208 } 212 }
209 213
210 /* The Guest has initialized. 214 /* The Guest has initialized.
211 * 215 *
212 * Look in the hypercall ring for the async hypercalls: */ 216 * Look in the hypercall ring for the async hypercalls: */
213 do_async_hcalls(lg); 217 do_async_hcalls(cpu);
214 218
215 /* If we stopped reading the hypercall ring because the Guest did a 219 /* If we stopped reading the hypercall ring because the Guest did a
216 * NOTIFY to the Launcher, we want to return now. Otherwise we do 220 * NOTIFY to the Launcher, we want to return now. Otherwise we do
217 * the hypercall. */ 221 * the hypercall. */
218 if (!lg->pending_notify) { 222 if (!cpu->lg->pending_notify) {
219 do_hcall(lg, lg->hcall); 223 do_hcall(cpu, cpu->hcall);
220 /* Tricky point: we reset the hcall pointer to mark the 224 /* Tricky point: we reset the hcall pointer to mark the
221 * hypercall as "done". We use the hcall pointer rather than 225 * hypercall as "done". We use the hcall pointer rather than
222 * the trap number to indicate a hypercall is pending. 226 * the trap number to indicate a hypercall is pending.
@@ -227,7 +231,7 @@ void do_hypercalls(struct lguest *lg)
227 * Launcher, the run_guest() loop will exit without running the 231 * Launcher, the run_guest() loop will exit without running the
228 * Guest. When it comes back it would try to re-run the 232 * Guest. When it comes back it would try to re-run the
229 * hypercall. */ 233 * hypercall. */
230 lg->hcall = NULL; 234 cpu->hcall = NULL;
231 } 235 }
232} 236}
233 237