aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/lguest/interrupts_and_traps.c
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2007-10-21 21:03:35 -0400
committerRusty Russell <rusty@rustcorp.com.au>2007-10-23 01:49:53 -0400
commitc18acd73ffc209def08003a1927473096f66c5ad (patch)
treedd8e292ac8ca90b061b7e37ad6947231ced566e3 /drivers/lguest/interrupts_and_traps.c
parentee3db0f2b6053b65f3b70253f5f810d9a3d67b28 (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.c49
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. */
20static unsigned int syscall_vector = SYSCALL_VECTOR;
21module_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: */
18static unsigned long idt_address(u32 lo, u32 hi) 24static 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. */
200static 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. */
207bool 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
217int 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
228void 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