Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+2 −5
Original line number Diff line number Diff line
@@ -20,13 +20,10 @@ extern unsigned long switcher_addr;
/* Found in switcher.S */
extern unsigned long default_idt_entries[];

/* Declarations for definitions in lguest_guest.S */
extern char lguest_noirq_start[], lguest_noirq_end[];
/* Declarations for definitions in arch/x86/lguest/head_32.S */
extern char lguest_noirq_iret[];
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_iret[], lgend_iret[];

extern void lguest_iret(void);
extern void lguest_init(void);
+1 −2
Original line number Diff line number Diff line
@@ -87,8 +87,7 @@

struct lguest_data lguest_data = {
	.hcall_status = { [0 ... LHCALL_RING_SIZE-1] = 0xFF },
	.noirq_start = (u32)lguest_noirq_start,
	.noirq_end = (u32)lguest_noirq_end,
	.noirq_iret = (u32)lguest_noirq_iret,
	.kernel_address = PAGE_OFFSET,
	.blocked_interrupts = { 1 }, /* Block timer interrupts */
	.syscall_vec = SYSCALL_VECTOR,
+6 −9
Original line number Diff line number Diff line
@@ -133,9 +133,8 @@ ENTRY(lg_restore_fl)
	ret
/*:*/

/* These demark the EIP range where host should never deliver interrupts. */
.global lguest_noirq_start
.global lguest_noirq_end
/* These demark the EIP where host should never deliver interrupts. */
.global lguest_noirq_iret

/*M:004
 * When the Host reflects a trap or injects an interrupt into the Guest, it
@@ -174,12 +173,11 @@ ENTRY(lg_restore_fl)
 *
 * 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
 * return to userspace or wherever.  Our solution to this is to surround the
 * code with lguest_noirq_start: and lguest_noirq_end: labels.  We tell the
 * return to userspace or wherever.  Our solution to this is to tell the
 * 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
 * data gets updated only after it completes, so we end up surrounding
 * just one instruction, iret).
 * data gets updated only after it completes, so we only need to protect
 * one instruction, iret).
 */
ENTRY(lguest_iret)
	pushl	2*4(%esp)
@@ -190,6 +188,5 @@ ENTRY(lguest_iret)
	 * prefix makes sure we use the stack segment, which is still valid.
	 */
	popl	%ss:lguest_data+LGUEST_DATA_irq_enabled
lguest_noirq_start:
lguest_noirq_iret:
	iret
lguest_noirq_end:
+2 −3
Original line number Diff line number Diff line
@@ -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 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)
	    || get_user(cpu->lg->noirq_end, &cpu->lg->lguest_data->noirq_end))
	if (get_user(cpu->lg->noirq_iret, &cpu->lg->lguest_data->noirq_iret))
		kill_guest(cpu, "bad guest page %p", cpu->lg->lguest_data);

	/*
+4 −4
Original line number Diff line number Diff line
@@ -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
	 * deliver interrupts.
	 */
	if (cpu->regs->eip >= cpu->lg->noirq_start &&
	   (cpu->regs->eip < cpu->lg->noirq_end))
	if (cpu->regs->eip == cpu->lg->noirq_iret)
		return;

	/* If they're halted, interrupts restart them. */
@@ -395,8 +394,9 @@ static bool direct_trap(unsigned int num)
 * 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
 * Guest, but the Guest needs the interrupts atomically disabled for an
 * interrupt gate.  It can do this by pointing the trap gate at instructions
 * within noirq_start and noirq_end, where it can safely disable interrupts.
 * interrupt gate.  The Host could provide a mechanism to register more
 * "no-interrupt" regions, and the Guest could point the trap gate at
 * instructions within that region, where it can safely disable interrupts.
 */

/*M:006
Loading