diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2007-10-21 21:03:35 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2007-10-23 01:49:53 -0400 |
commit | c18acd73ffc209def08003a1927473096f66c5ad (patch) | |
tree | dd8e292ac8ca90b061b7e37ad6947231ced566e3 /drivers/lguest/interrupts_and_traps.c | |
parent | ee3db0f2b6053b65f3b70253f5f810d9a3d67b28 (diff) |
Allow guest to specify syscall vector to use.
(Based on Ron Minnich's LGUEST_PLAN9_SYSCALL patch).
This patch allows Guests to specify what system call vector they want,
and we try to reserve it. We only allow one non-Linux system call
vector, to try to avoid DoS on the Host.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers/lguest/interrupts_and_traps.c')
-rw-r--r-- | drivers/lguest/interrupts_and_traps.c | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/drivers/lguest/interrupts_and_traps.c b/drivers/lguest/interrupts_and_traps.c index fdefc0afc38c..a57d757eab6e 100644 --- a/drivers/lguest/interrupts_and_traps.c +++ b/drivers/lguest/interrupts_and_traps.c | |||
@@ -12,8 +12,14 @@ | |||
12 | * them first, so we also have a way of "reflecting" them into the Guest as if | 12 | * them first, so we also have a way of "reflecting" them into the Guest as if |
13 | * they had been delivered to it directly. :*/ | 13 | * they had been delivered to it directly. :*/ |
14 | #include <linux/uaccess.h> | 14 | #include <linux/uaccess.h> |
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/module.h> | ||
15 | #include "lg.h" | 17 | #include "lg.h" |
16 | 18 | ||
19 | /* Allow Guests to use a non-128 (ie. non-Linux) syscall trap. */ | ||
20 | static unsigned int syscall_vector = SYSCALL_VECTOR; | ||
21 | module_param(syscall_vector, uint, 0444); | ||
22 | |||
17 | /* The address of the interrupt handler is split into two bits: */ | 23 | /* The address of the interrupt handler is split into two bits: */ |
18 | static unsigned long idt_address(u32 lo, u32 hi) | 24 | static unsigned long idt_address(u32 lo, u32 hi) |
19 | { | 25 | { |
@@ -183,6 +189,47 @@ void maybe_do_interrupt(struct lguest *lg) | |||
183 | * timer interrupt. */ | 189 | * timer interrupt. */ |
184 | write_timestamp(lg); | 190 | write_timestamp(lg); |
185 | } | 191 | } |
192 | /*:*/ | ||
193 | |||
194 | /* Linux uses trap 128 for system calls. Plan9 uses 64, and Ron Minnich sent | ||
195 | * me a patch, so we support that too. It'd be a big step for lguest if half | ||
196 | * the Plan 9 user base were to start using it. | ||
197 | * | ||
198 | * Actually now I think of it, it's possible that Ron *is* half the Plan 9 | ||
199 | * userbase. Oh well. */ | ||
200 | static bool could_be_syscall(unsigned int num) | ||
201 | { | ||
202 | /* Normal Linux SYSCALL_VECTOR or reserved vector? */ | ||
203 | return num == SYSCALL_VECTOR || num == syscall_vector; | ||
204 | } | ||
205 | |||
206 | /* The syscall vector it wants must be unused by Host. */ | ||
207 | bool check_syscall_vector(struct lguest *lg) | ||
208 | { | ||
209 | u32 vector; | ||
210 | |||
211 | if (get_user(vector, &lg->lguest_data->syscall_vec)) | ||
212 | return false; | ||
213 | |||
214 | return could_be_syscall(vector); | ||
215 | } | ||
216 | |||
217 | int init_interrupts(void) | ||
218 | { | ||
219 | /* If they want some strange system call vector, reserve it now */ | ||
220 | if (syscall_vector != SYSCALL_VECTOR | ||
221 | && test_and_set_bit(syscall_vector, used_vectors)) { | ||
222 | printk("lg: couldn't reserve syscall %u\n", syscall_vector); | ||
223 | return -EBUSY; | ||
224 | } | ||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | void free_interrupts(void) | ||
229 | { | ||
230 | if (syscall_vector != SYSCALL_VECTOR) | ||
231 | clear_bit(syscall_vector, used_vectors); | ||
232 | } | ||
186 | 233 | ||
187 | /*H:220 Now we've got the routines to deliver interrupts, delivering traps | 234 | /*H:220 Now we've got the routines to deliver interrupts, delivering traps |
188 | * like page fault is easy. The only trick is that Intel decided that some | 235 | * like page fault is easy. The only trick is that Intel decided that some |
@@ -224,7 +271,7 @@ static int direct_trap(unsigned int num) | |||
224 | { | 271 | { |
225 | /* Hardware interrupts don't go to the Guest at all (except system | 272 | /* Hardware interrupts don't go to the Guest at all (except system |
226 | * call). */ | 273 | * call). */ |
227 | if (num >= FIRST_EXTERNAL_VECTOR && num != SYSCALL_VECTOR) | 274 | if (num >= FIRST_EXTERNAL_VECTOR && !could_be_syscall(num)) |
228 | return 0; | 275 | return 0; |
229 | 276 | ||
230 | /* The Host needs to see page faults (for shadow paging and to save the | 277 | /* The Host needs to see page faults (for shadow paging and to save the |