diff options
-rw-r--r-- | drivers/lguest/interrupts_and_traps.c | 6 | ||||
-rw-r--r-- | drivers/lguest/lg.h | 1 | ||||
-rw-r--r-- | drivers/lguest/x86/core.c | 6 |
3 files changed, 11 insertions, 2 deletions
diff --git a/drivers/lguest/interrupts_and_traps.c b/drivers/lguest/interrupts_and_traps.c index eb934b0242e0..67392b6ab845 100644 --- a/drivers/lguest/interrupts_and_traps.c +++ b/drivers/lguest/interrupts_and_traps.c | |||
@@ -331,7 +331,7 @@ void set_interrupt(struct lg_cpu *cpu, unsigned int irq) | |||
331 | * Actually now I think of it, it's possible that Ron *is* half the Plan 9 | 331 | * Actually now I think of it, it's possible that Ron *is* half the Plan 9 |
332 | * userbase. Oh well. | 332 | * userbase. Oh well. |
333 | */ | 333 | */ |
334 | static bool could_be_syscall(unsigned int num) | 334 | bool could_be_syscall(unsigned int num) |
335 | { | 335 | { |
336 | /* Normal Linux IA32_SYSCALL_VECTOR or reserved vector? */ | 336 | /* Normal Linux IA32_SYSCALL_VECTOR or reserved vector? */ |
337 | return num == IA32_SYSCALL_VECTOR || num == syscall_vector; | 337 | return num == IA32_SYSCALL_VECTOR || num == syscall_vector; |
@@ -416,6 +416,10 @@ bool deliver_trap(struct lg_cpu *cpu, unsigned int num) | |||
416 | * | 416 | * |
417 | * This routine indicates if a particular trap number could be delivered | 417 | * This routine indicates if a particular trap number could be delivered |
418 | * directly. | 418 | * directly. |
419 | * | ||
420 | * Unfortunately, Linux 4.6 started using an interrupt gate instead of a | ||
421 | * trap gate for syscalls, so this trick is ineffective. See Mastery for | ||
422 | * how we could do this anyway... | ||
419 | */ | 423 | */ |
420 | static bool direct_trap(unsigned int num) | 424 | static bool direct_trap(unsigned int num) |
421 | { | 425 | { |
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h index ac8ad0461e80..69b3814afd2f 100644 --- a/drivers/lguest/lg.h +++ b/drivers/lguest/lg.h | |||
@@ -167,6 +167,7 @@ void guest_set_clockevent(struct lg_cpu *cpu, unsigned long delta); | |||
167 | bool send_notify_to_eventfd(struct lg_cpu *cpu); | 167 | bool send_notify_to_eventfd(struct lg_cpu *cpu); |
168 | void init_clockdev(struct lg_cpu *cpu); | 168 | void init_clockdev(struct lg_cpu *cpu); |
169 | bool check_syscall_vector(struct lguest *lg); | 169 | bool check_syscall_vector(struct lguest *lg); |
170 | bool could_be_syscall(unsigned int num); | ||
170 | int init_interrupts(void); | 171 | int init_interrupts(void); |
171 | void free_interrupts(void); | 172 | void free_interrupts(void); |
172 | 173 | ||
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c index 6a4cd771a2be..adc162c7040d 100644 --- a/drivers/lguest/x86/core.c +++ b/drivers/lguest/x86/core.c | |||
@@ -429,8 +429,12 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu) | |||
429 | return; | 429 | return; |
430 | break; | 430 | break; |
431 | case 32 ... 255: | 431 | case 32 ... 255: |
432 | /* This might be a syscall. */ | ||
433 | if (could_be_syscall(cpu->regs->trapnum)) | ||
434 | break; | ||
435 | |||
432 | /* | 436 | /* |
433 | * These values mean a real interrupt occurred, in which case | 437 | * Other values mean a real interrupt occurred, in which case |
434 | * the Host handler has already been run. We just do a | 438 | * the Host handler has already been run. We just do a |
435 | * friendly check if another process should now be run, then | 439 | * friendly check if another process should now be run, then |
436 | * return to run the Guest again. | 440 | * return to run the Guest again. |