Re: [PATCH] lguest: simplify lguest_iret

2015-03-24 Thread Rusty Russell
Denys Vlasenko  writes:
> On 03/23/2015 04:30 AM, Rusty Russell wrote:
>> + * They may be about to iret, where they asked us never to
>> + * deliver interrupts.  In this case, we can emulate that iret
>> + * then immediately deliver the interrupt.  This is bascially
>> + * a noop: the iret would pop the interrupt frame and restore
>> + * eflags, and then we'd set it up again.  So just restore the
>> + * eflags word and jump straight to the handler in this case.
>>   */
>> +if (cpu->regs->eip >= cpu->lg->noirq_start &&
>> +(cpu->regs->eip < cpu->lg->noirq_end)) {
>> +restore_eflags(cpu);
>
> In truth, this is not _exactly_ true for irets to CPL3.
>
> If a new interrupt comes right after iret, then
> a new transition to CPL0 will happen.
>
> This means ss:esp will be loaded from tss.ss0:tss.sp0.
>
> Meaning, that the new iret frame may be in a different place
> than the one which was used by iret.

True.  We could check the to-be-restored-CPL and reset the sp.  Instead,
I've added this comment:

/*
 * They may be about to iret, where they asked us never to
 * deliver interrupts.  In this case, we can emulate that iret
 * then immediately deliver the interrupt.  This is basically
 * a noop: the iret would pop the interrupt frame and restore
 * eflags, and then we'd set it up again.  So just restore the
 * eflags word and jump straight to the handler in this case.
 *
 * Denys Vlasenko points out that this isn't quite right: if
 * the iret was returning to userspace, then that interrupt
 * would reset the stack pointer (which the Guest told us
 * about via LHCALL_SET_STACK).  But unless the Guest is being
 * *really* weird, that will be the same as the current stack
 * anyway.
 */

> There is no good reason for CPL0 code to move iret frame around,
> but who knows. As an example, look what 32-bit Linux kernel does
> with NMI iret frames... it's mind bending.

Fortunately, lguest is allergic to NMIs :)

Thanks!
Rusty.


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] lguest: simplify lguest_iret

2015-03-24 Thread Denys Vlasenko
On 03/23/2015 04:30 AM, Rusty Russell wrote:
> Denys Vlasenko  writes:
>> Signed-off-by: Denys Vlasenko 
>> CC: lgu...@lists.ozlabs.org
>> CC: x...@kernel.org
>> CC: linux-kernel@vger.kernel.org
> 
> Oh, thanks, applied!
> 
> And now it's down to one instruction, we could change
> try_deliver_interrupt() to handle this case (rather than ignoring the
> interrupt altogether): just jump to the handler and leave the
> stack set up.
> 
> Here's a pair of inline patches which attempt to do that (untested!).
> 
> Thanks,
> Rusty.
> 
> 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: Rusty Russell 
> 
> diff --git a/arch/x86/include/asm/lguest.h b/arch/x86/include/asm/lguest.h
> index e2d4a4afa8c3..3bbc07a57a31 100644
> --- a/arch/x86/include/asm/lguest.h
> +++ b/arch/x86/include/asm/lguest.h
> @@ -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);
> diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
> index ac4453d8520e..4c8cf656f21f 100644
> --- a/arch/x86/lguest/boot.c
> +++ b/arch/x86/lguest/boot.c
> @@ -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,
> diff --git a/arch/x86/lguest/head_32.S b/arch/x86/lguest/head_32.S
> index 583732cc5d18..128fe93161b4 100644
> --- a/arch/x86/lguest/head_32.S
> +++ b/arch/x86/lguest/head_32.S
> @@ -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:
> diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
> index 1219af493c0f..19a32280731d 100644
> --- a/drivers/lguest/hypercalls.c
> +++ b/drivers/lguest/hypercalls.c
> @@ -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, >lg->lguest_data->noirq_start)
> - || get_user(cpu->lg->noirq_end, >lg->lguest_data->noirq_end))
> + if (get_user(cpu->lg->noirq_iret, >lg->lguest_data->noirq_iret))
>   kill_guest(cpu, "bad guest page %p", cpu->lg->lguest_data);
>  
>   /*
> diff --git a/drivers/lguest/interrupts_and_traps.c 
> b/drivers/lguest/interrupts_and_traps.c
> index 70dfcdc29f1f..6d4c072b61e1 100644
> --- 

Re: [PATCH] lguest: simplify lguest_iret

2015-03-24 Thread Denys Vlasenko
On 03/23/2015 04:30 AM, Rusty Russell wrote:
 Denys Vlasenko dvlas...@redhat.com writes:
 Signed-off-by: Denys Vlasenko dvlas...@redhat.com
 CC: lgu...@lists.ozlabs.org
 CC: x...@kernel.org
 CC: linux-kernel@vger.kernel.org
 
 Oh, thanks, applied!
 
 And now it's down to one instruction, we could change
 try_deliver_interrupt() to handle this case (rather than ignoring the
 interrupt altogether): just jump to the handler and leave the
 stack set up.
 
 Here's a pair of inline patches which attempt to do that (untested!).
 
 Thanks,
 Rusty.
 
 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: Rusty Russell ru...@rustcorp.com.au
 
 diff --git a/arch/x86/include/asm/lguest.h b/arch/x86/include/asm/lguest.h
 index e2d4a4afa8c3..3bbc07a57a31 100644
 --- a/arch/x86/include/asm/lguest.h
 +++ b/arch/x86/include/asm/lguest.h
 @@ -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);
 diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
 index ac4453d8520e..4c8cf656f21f 100644
 --- a/arch/x86/lguest/boot.c
 +++ b/arch/x86/lguest/boot.c
 @@ -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,
 diff --git a/arch/x86/lguest/head_32.S b/arch/x86/lguest/head_32.S
 index 583732cc5d18..128fe93161b4 100644
 --- a/arch/x86/lguest/head_32.S
 +++ b/arch/x86/lguest/head_32.S
 @@ -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:
 diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
 index 1219af493c0f..19a32280731d 100644
 --- a/drivers/lguest/hypercalls.c
 +++ b/drivers/lguest/hypercalls.c
 @@ -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);
  
   /*
 diff --git a/drivers/lguest/interrupts_and_traps.c 
 b/drivers/lguest/interrupts_and_traps.c
 index 70dfcdc29f1f..6d4c072b61e1 100644
 --- a/drivers/lguest/interrupts_and_traps.c
 +++ b/drivers/lguest/interrupts_and_traps.c
 @@ -204,8 +204,7 @@ 

Re: [PATCH] lguest: simplify lguest_iret

2015-03-24 Thread Rusty Russell
Denys Vlasenko dvlas...@redhat.com writes:
 On 03/23/2015 04:30 AM, Rusty Russell wrote:
 + * They may be about to iret, where they asked us never to
 + * deliver interrupts.  In this case, we can emulate that iret
 + * then immediately deliver the interrupt.  This is bascially
 + * a noop: the iret would pop the interrupt frame and restore
 + * eflags, and then we'd set it up again.  So just restore the
 + * eflags word and jump straight to the handler in this case.
   */
 +if (cpu-regs-eip = cpu-lg-noirq_start 
 +(cpu-regs-eip  cpu-lg-noirq_end)) {
 +restore_eflags(cpu);

 In truth, this is not _exactly_ true for irets to CPL3.

 If a new interrupt comes right after iret, then
 a new transition to CPL0 will happen.

 This means ss:esp will be loaded from tss.ss0:tss.sp0.

 Meaning, that the new iret frame may be in a different place
 than the one which was used by iret.

True.  We could check the to-be-restored-CPL and reset the sp.  Instead,
I've added this comment:

/*
 * They may be about to iret, where they asked us never to
 * deliver interrupts.  In this case, we can emulate that iret
 * then immediately deliver the interrupt.  This is basically
 * a noop: the iret would pop the interrupt frame and restore
 * eflags, and then we'd set it up again.  So just restore the
 * eflags word and jump straight to the handler in this case.
 *
 * Denys Vlasenko points out that this isn't quite right: if
 * the iret was returning to userspace, then that interrupt
 * would reset the stack pointer (which the Guest told us
 * about via LHCALL_SET_STACK).  But unless the Guest is being
 * *really* weird, that will be the same as the current stack
 * anyway.
 */

 There is no good reason for CPL0 code to move iret frame around,
 but who knows. As an example, look what 32-bit Linux kernel does
 with NMI iret frames... it's mind bending.

Fortunately, lguest is allergic to NMIs :)

Thanks!
Rusty.


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] lguest: simplify lguest_iret

2015-03-22 Thread Rusty Russell
Denys Vlasenko  writes:
> Signed-off-by: Denys Vlasenko 
> CC: lgu...@lists.ozlabs.org
> CC: x...@kernel.org
> CC: linux-kernel@vger.kernel.org

Oh, thanks, applied!

And now it's down to one instruction, we could change
try_deliver_interrupt() to handle this case (rather than ignoring the
interrupt altogether): just jump to the handler and leave the
stack set up.

Here's a pair of inline patches which attempt to do that (untested!).

Thanks,
Rusty.

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: Rusty Russell 

diff --git a/arch/x86/include/asm/lguest.h b/arch/x86/include/asm/lguest.h
index e2d4a4afa8c3..3bbc07a57a31 100644
--- a/arch/x86/include/asm/lguest.h
+++ b/arch/x86/include/asm/lguest.h
@@ -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);
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index ac4453d8520e..4c8cf656f21f 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -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,
diff --git a/arch/x86/lguest/head_32.S b/arch/x86/lguest/head_32.S
index 583732cc5d18..128fe93161b4 100644
--- a/arch/x86/lguest/head_32.S
+++ b/arch/x86/lguest/head_32.S
@@ -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:
diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index 1219af493c0f..19a32280731d 100644
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -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, >lg->lguest_data->noirq_start)
-   || get_user(cpu->lg->noirq_end, >lg->lguest_data->noirq_end))
+   if (get_user(cpu->lg->noirq_iret, >lg->lguest_data->noirq_iret))
kill_guest(cpu, "bad guest page %p", cpu->lg->lguest_data);
 
/*
diff --git a/drivers/lguest/interrupts_and_traps.c 
b/drivers/lguest/interrupts_and_traps.c
index 70dfcdc29f1f..6d4c072b61e1 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -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
 * 

Re: [PATCH] lguest: simplify lguest_iret

2015-03-22 Thread Rusty Russell
Denys Vlasenko dvlas...@redhat.com writes:
 Signed-off-by: Denys Vlasenko dvlas...@redhat.com
 CC: lgu...@lists.ozlabs.org
 CC: x...@kernel.org
 CC: linux-kernel@vger.kernel.org

Oh, thanks, applied!

And now it's down to one instruction, we could change
try_deliver_interrupt() to handle this case (rather than ignoring the
interrupt altogether): just jump to the handler and leave the
stack set up.

Here's a pair of inline patches which attempt to do that (untested!).

Thanks,
Rusty.

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: Rusty Russell ru...@rustcorp.com.au

diff --git a/arch/x86/include/asm/lguest.h b/arch/x86/include/asm/lguest.h
index e2d4a4afa8c3..3bbc07a57a31 100644
--- a/arch/x86/include/asm/lguest.h
+++ b/arch/x86/include/asm/lguest.h
@@ -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);
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index ac4453d8520e..4c8cf656f21f 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -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,
diff --git a/arch/x86/lguest/head_32.S b/arch/x86/lguest/head_32.S
index 583732cc5d18..128fe93161b4 100644
--- a/arch/x86/lguest/head_32.S
+++ b/arch/x86/lguest/head_32.S
@@ -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:
diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index 1219af493c0f..19a32280731d 100644
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -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);
 
/*
diff --git a/drivers/lguest/interrupts_and_traps.c 
b/drivers/lguest/interrupts_and_traps.c
index 70dfcdc29f1f..6d4c072b61e1 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -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