Commit 2f921b5b authored by Rusty Russell's avatar Rusty Russell

lguest: suppress interrupts for single insn, not range.

The last patch reduced our interrupt-suppression region to one address,
so simplify the code somewhat.

Also, remove the obsolete undefined instruction ranges and the comment
which refers to lguest_guest.S instead of head_32.S.
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent 7042cb4e
...@@ -20,13 +20,10 @@ extern unsigned long switcher_addr; ...@@ -20,13 +20,10 @@ extern unsigned long switcher_addr;
/* Found in switcher.S */ /* Found in switcher.S */
extern unsigned long default_idt_entries[]; extern unsigned long default_idt_entries[];
/* Declarations for definitions in lguest_guest.S */ /* Declarations for definitions in arch/x86/lguest/head_32.S */
extern char lguest_noirq_start[], lguest_noirq_end[]; extern char lguest_noirq_iret[];
extern const char lgstart_cli[], lgend_cli[]; extern const char lgstart_cli[], lgend_cli[];
extern const char lgstart_sti[], lgend_sti[];
extern const char lgstart_popf[], lgend_popf[];
extern const char lgstart_pushf[], lgend_pushf[]; extern const char lgstart_pushf[], lgend_pushf[];
extern const char lgstart_iret[], lgend_iret[];
extern void lguest_iret(void); extern void lguest_iret(void);
extern void lguest_init(void); extern void lguest_init(void);
......
...@@ -87,8 +87,7 @@ ...@@ -87,8 +87,7 @@
struct lguest_data lguest_data = { struct lguest_data lguest_data = {
.hcall_status = { [0 ... LHCALL_RING_SIZE-1] = 0xFF }, .hcall_status = { [0 ... LHCALL_RING_SIZE-1] = 0xFF },
.noirq_start = (u32)lguest_noirq_start, .noirq_iret = (u32)lguest_noirq_iret,
.noirq_end = (u32)lguest_noirq_end,
.kernel_address = PAGE_OFFSET, .kernel_address = PAGE_OFFSET,
.blocked_interrupts = { 1 }, /* Block timer interrupts */ .blocked_interrupts = { 1 }, /* Block timer interrupts */
.syscall_vec = SYSCALL_VECTOR, .syscall_vec = SYSCALL_VECTOR,
......
...@@ -133,9 +133,8 @@ ENTRY(lg_restore_fl) ...@@ -133,9 +133,8 @@ ENTRY(lg_restore_fl)
ret ret
/*:*/ /*:*/
/* These demark the EIP range where host should never deliver interrupts. */ /* These demark the EIP where host should never deliver interrupts. */
.global lguest_noirq_start .global lguest_noirq_iret
.global lguest_noirq_end
/*M:004 /*M:004
* When the Host reflects a trap or injects an interrupt into the Guest, it * When the Host reflects a trap or injects an interrupt into the Guest, it
...@@ -174,12 +173,11 @@ ENTRY(lg_restore_fl) ...@@ -174,12 +173,11 @@ ENTRY(lg_restore_fl)
* *
* The second is harder: copying eflags to lguest_data.irq_enabled will turn * The second is harder: copying eflags to lguest_data.irq_enabled will turn
* interrupts on before we're finished, so we could be interrupted before we * interrupts on before we're finished, so we could be interrupted before we
* return to userspace or wherever. Our solution to this is to surround the * return to userspace or wherever. Our solution to this is to tell the
* code with lguest_noirq_start: and lguest_noirq_end: labels. We tell the
* Host that it is *never* to interrupt us there, even if interrupts seem to be * Host that it is *never* to interrupt us there, even if interrupts seem to be
* enabled. (It's not necessary to protect pop instruction, since * enabled. (It's not necessary to protect pop instruction, since
* data gets updated only after it completes, so we end up surrounding * data gets updated only after it completes, so we only need to protect
* just one instruction, iret). * one instruction, iret).
*/ */
ENTRY(lguest_iret) ENTRY(lguest_iret)
pushl 2*4(%esp) pushl 2*4(%esp)
...@@ -190,6 +188,5 @@ ENTRY(lguest_iret) ...@@ -190,6 +188,5 @@ ENTRY(lguest_iret)
* prefix makes sure we use the stack segment, which is still valid. * prefix makes sure we use the stack segment, which is still valid.
*/ */
popl %ss:lguest_data+LGUEST_DATA_irq_enabled popl %ss:lguest_data+LGUEST_DATA_irq_enabled
lguest_noirq_start: lguest_noirq_iret:
iret iret
lguest_noirq_end:
...@@ -211,10 +211,9 @@ static void initialize(struct lg_cpu *cpu) ...@@ -211,10 +211,9 @@ static void initialize(struct lg_cpu *cpu)
/* /*
* The Guest tells us where we're not to deliver interrupts by putting * The Guest tells us where we're not to deliver interrupts by putting
* the range of addresses into "struct lguest_data". * the instruction address into "struct lguest_data".
*/ */
if (get_user(cpu->lg->noirq_start, &cpu->lg->lguest_data->noirq_start) if (get_user(cpu->lg->noirq_iret, &cpu->lg->lguest_data->noirq_iret))
|| get_user(cpu->lg->noirq_end, &cpu->lg->lguest_data->noirq_end))
kill_guest(cpu, "bad guest page %p", cpu->lg->lguest_data); kill_guest(cpu, "bad guest page %p", cpu->lg->lguest_data);
/* /*
......
...@@ -204,8 +204,7 @@ void try_deliver_interrupt(struct lg_cpu *cpu, unsigned int irq, bool more) ...@@ -204,8 +204,7 @@ void try_deliver_interrupt(struct lg_cpu *cpu, unsigned int irq, bool more)
* They may be in the middle of an iret, where they asked us never to * They may be in the middle of an iret, where they asked us never to
* deliver interrupts. * deliver interrupts.
*/ */
if (cpu->regs->eip >= cpu->lg->noirq_start && if (cpu->regs->eip == cpu->lg->noirq_iret)
(cpu->regs->eip < cpu->lg->noirq_end))
return; return;
/* If they're halted, interrupts restart them. */ /* If they're halted, interrupts restart them. */
...@@ -395,8 +394,9 @@ static bool direct_trap(unsigned int num) ...@@ -395,8 +394,9 @@ static bool direct_trap(unsigned int num)
* The Guest has the ability to turn its interrupt gates into trap gates, * The Guest has the ability to turn its interrupt gates into trap gates,
* if it is careful. The Host will let trap gates can go directly to the * if it is careful. The Host will let trap gates can go directly to the
* Guest, but the Guest needs the interrupts atomically disabled for an * Guest, but the Guest needs the interrupts atomically disabled for an
* interrupt gate. It can do this by pointing the trap gate at instructions * interrupt gate. The Host could provide a mechanism to register more
* within noirq_start and noirq_end, where it can safely disable interrupts. * "no-interrupt" regions, and the Guest could point the trap gate at
* instructions within that region, where it can safely disable interrupts.
*/ */
/*M:006 /*M:006
......
...@@ -102,7 +102,7 @@ struct lguest { ...@@ -102,7 +102,7 @@ struct lguest {
struct pgdir pgdirs[4]; struct pgdir pgdirs[4];
unsigned long noirq_start, noirq_end; unsigned long noirq_iret;
unsigned int stack_pages; unsigned int stack_pages;
u32 tsc_khz; u32 tsc_khz;
......
...@@ -61,8 +61,8 @@ struct lguest_data { ...@@ -61,8 +61,8 @@ struct lguest_data {
u32 tsc_khz; u32 tsc_khz;
/* Fields initialized by the Guest at boot: */ /* Fields initialized by the Guest at boot: */
/* Instruction range to suppress interrupts even if enabled */ /* Instruction to suppress interrupts even if enabled */
unsigned long noirq_start, noirq_end; unsigned long noirq_iret;
/* Address above which page tables are all identical. */ /* Address above which page tables are all identical. */
unsigned long kernel_address; unsigned long kernel_address;
/* The vector to try to use for system calls (0x40 or 0x80). */ /* The vector to try to use for system calls (0x40 or 0x80). */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment