aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/lguest/hypercalls.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/lguest/hypercalls.c')
-rw-r--r--drivers/lguest/hypercalls.c26
1 files changed, 8 insertions, 18 deletions
diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index 13b5f2f813de..3a53788ba450 100644
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -60,22 +60,9 @@ static void do_hcall(struct lguest *lg, struct hcall_args *args)
60 else 60 else
61 guest_pagetable_flush_user(lg); 61 guest_pagetable_flush_user(lg);
62 break; 62 break;
63 case LHCALL_BIND_DMA:
64 /* BIND_DMA really wants four arguments, but it's the only call
65 * which does. So the Guest packs the number of buffers and
66 * the interrupt number into the final argument, and we decode
67 * it here. This can legitimately fail, since we currently
68 * place a limit on the number of DMA pools a Guest can have.
69 * So we return true or false from this call. */
70 args->arg0 = bind_dma(lg, args->arg1, args->arg2,
71 args->arg3 >> 8, args->arg3 & 0xFF);
72 break;
73 63
74 /* All these calls simply pass the arguments through to the right 64 /* All these calls simply pass the arguments through to the right
75 * routines. */ 65 * routines. */
76 case LHCALL_SEND_DMA:
77 send_dma(lg, args->arg1, args->arg2);
78 break;
79 case LHCALL_NEW_PGTABLE: 66 case LHCALL_NEW_PGTABLE:
80 guest_new_pagetable(lg, args->arg1); 67 guest_new_pagetable(lg, args->arg1);
81 break; 68 break;
@@ -99,6 +86,9 @@ static void do_hcall(struct lguest *lg, struct hcall_args *args)
99 /* Similarly, this sets the halted flag for run_guest(). */ 86 /* Similarly, this sets the halted flag for run_guest(). */
100 lg->halted = 1; 87 lg->halted = 1;
101 break; 88 break;
89 case LHCALL_NOTIFY:
90 lg->pending_notify = args->arg1;
91 break;
102 default: 92 default:
103 if (lguest_arch_do_hcall(lg, args)) 93 if (lguest_arch_do_hcall(lg, args))
104 kill_guest(lg, "Bad hypercall %li\n", args->arg0); 94 kill_guest(lg, "Bad hypercall %li\n", args->arg0);
@@ -156,9 +146,9 @@ static void do_async_hcalls(struct lguest *lg)
156 break; 146 break;
157 } 147 }
158 148
159 /* Stop doing hypercalls if we've just done a DMA to the 149 /* Stop doing hypercalls if they want to notify the Launcher:
160 * Launcher: it needs to service this first. */ 150 * it needs to service this first. */
161 if (lg->dma_is_pending) 151 if (lg->pending_notify)
162 break; 152 break;
163 } 153 }
164} 154}
@@ -220,9 +210,9 @@ void do_hypercalls(struct lguest *lg)
220 do_async_hcalls(lg); 210 do_async_hcalls(lg);
221 211
222 /* If we stopped reading the hypercall ring because the Guest did a 212 /* If we stopped reading the hypercall ring because the Guest did a
223 * SEND_DMA to the Launcher, we want to return now. Otherwise we do 213 * NOTIFY to the Launcher, we want to return now. Otherwise we do
224 * the hypercall. */ 214 * the hypercall. */
225 if (!lg->dma_is_pending) { 215 if (!lg->pending_notify) {
226 do_hcall(lg, lg->hcall); 216 do_hcall(lg, lg->hcall);
227 /* Tricky point: we reset the hcall pointer to mark the 217 /* Tricky point: we reset the hcall pointer to mark the
228 * hypercall as "done". We use the hcall pointer rather than 218 * hypercall as "done". We use the hcall pointer rather than