Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 72253
b: refs/heads/master
c: cc6d4fb
h: refs/heads/master
i:
  72251: f399699
v: v3
  • Loading branch information
Rusty Russell committed Oct 23, 2007
1 parent 2361555 commit 261db91
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 39 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4614a3a3b638dfd7a67d0237944f6a76331af61d
refs/heads/master: cc6d4fbcef328acdc9fa7023e69f39f753f72fe1
8 changes: 4 additions & 4 deletions trunk/drivers/lguest/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,10 +198,10 @@ int run_guest(struct lguest *lg, unsigned long __user *user)
{
/* We stop running once the Guest is dead. */
while (!lg->dead) {
/* First we run any hypercalls the Guest wants done: either in
* the hypercall ring in "struct lguest_data", or directly by
* using int 31 (LGUEST_TRAP_ENTRY). */
do_hypercalls(lg);
/* First we run any hypercalls the Guest wants done. */
if (lg->hcall)
do_hypercalls(lg);

/* It's possible the Guest did a SEND_DMA hypercall to the
* Launcher, in which case we return from the read() now. */
if (lg->dma_is_pending) {
Expand Down
48 changes: 20 additions & 28 deletions trunk/drivers/lguest/hypercalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,19 +241,6 @@ static void initialize(struct lguest *lg)
* is one other way we can do things for the Guest, as we see in
* emulate_insn(). */

/*H:110 Tricky point: we mark the hypercall as "done" once we've done it.
* Normally we don't need to do this: the Guest will run again and update the
* trap number before we come back around the run_guest() loop to
* do_hypercalls().
*
* However, if we are signalled or the Guest sends DMA to the Launcher, that
* loop will exit without running the Guest. When it comes back it would try
* to re-run the hypercall. */
static void clear_hcall(struct lguest *lg)
{
lg->regs->trapnum = 255;
}

/*H:100
* Hypercalls
*
Expand All @@ -262,16 +249,12 @@ static void clear_hcall(struct lguest *lg)
*/
void do_hypercalls(struct lguest *lg)
{
/* Not initialized yet? */
/* Not initialized yet? This hypercall must do it. */
if (unlikely(!lg->lguest_data)) {
/* Did the Guest make a hypercall? We might have come back for
* some other reason (an interrupt, a different trap). */
if (lg->regs->trapnum == LGUEST_TRAP_ENTRY) {
/* Set up the "struct lguest_data" */
initialize(lg);
/* The hypercall is done. */
clear_hcall(lg);
}
/* Set up the "struct lguest_data" */
initialize(lg);
/* Hcall is done. */
lg->hcall = NULL;
return;
}

Expand All @@ -281,12 +264,21 @@ void do_hypercalls(struct lguest *lg)
do_async_hcalls(lg);

/* If we stopped reading the hypercall ring because the Guest did a
* SEND_DMA to the Launcher, we want to return now. Otherwise if the
* Guest asked us to do a hypercall, we do it. */
if (!lg->dma_is_pending && lg->regs->trapnum == LGUEST_TRAP_ENTRY) {
do_hcall(lg, lg->regs);
/* The hypercall is done. */
clear_hcall(lg);
* SEND_DMA to the Launcher, we want to return now. Otherwise we do
* the hypercall. */
if (!lg->dma_is_pending) {
do_hcall(lg, lg->hcall);
/* Tricky point: we reset the hcall pointer to mark the
* hypercall as "done". We use the hcall pointer rather than
* the trap number to indicate a hypercall is pending.
* Normally it doesn't matter: the Guest will run again and
* update the trap number before we come back here.
*
* However, if we are signalled or the Guest sends DMA to the
* Launcher, the run_guest() loop will exit without running the
* Guest. When it comes back it would try to re-run the
* hypercall. */
lg->hcall = NULL;
}
}

Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/lguest/lg.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ struct lguest
u32 esp1;
u8 ss1;

/* If a hypercall was asked for, this points to the arguments. */
struct lguest_regs *hcall;

/* Do we need to stop what we're doing and return to userspace? */
int break_out;
wait_queue_head_t break_wq;
Expand Down
13 changes: 7 additions & 6 deletions trunk/drivers/lguest/x86/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,13 +316,14 @@ void lguest_arch_handle_trap(struct lguest *lg)
return;
break;
case 32 ... 255:
/* These values mean a real interrupt occurred, in
* which case the Host handler has already been run.
* We just do a friendly check if another process
* should now be run, then fall through to loop
* around: */
/* These values mean a real interrupt occurred, in which case
* the Host handler has already been run. We just do a
* friendly check if another process should now be run, then
* return to run the Guest again */
cond_resched();
case LGUEST_TRAP_ENTRY: /* Handled before re-entering Guest */
return;
case LGUEST_TRAP_ENTRY:
lg->hcall = lg->regs;
return;
}

Expand Down

0 comments on commit 261db91

Please sign in to comment.