diff options
Diffstat (limited to 'drivers/lguest/hypercalls.c')
-rw-r--r-- | drivers/lguest/hypercalls.c | 26 |
1 files changed, 8 insertions, 18 deletions
diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c index 13b5f2f813d..3a53788ba45 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 |