Re: [PATCH] kvm/ppc/booke64: Hard disable interrupts when entering the guest

2013-05-06 Thread Scott Wood

On 05/05/2013 04:03:08 PM, Benjamin Herrenschmidt wrote:

On Fri, 2013-05-03 at 18:45 -0500, Scott Wood wrote:
 kvmppc_lazy_ee_enable() was causing interrupts to be soft-enabled
 (albeit hard-disabled) in kvmppc_restart_interrupt().  This led to
 warnings, and possibly breakage if the interrupt state was later  
saved

 and then restored (leading to interrupts being hard-and-soft enabled
 when they should be at least soft-disabled).

 Simply removing kvmppc_lazy_ee_enable() leaves interrupts only
 soft-disabled when we enter the guest, but they will be  
hard-disabled
 when we exit the guest -- without PACA_IRQ_HARD_DIS ever being set,  
so

 the local_irq_enable() fails to hard-enable.

 While we could just set PACA_IRQ_HARD_DIS after an exit to  
compensate,
 instead hard-disable interrupts before entering the guest.  This  
way,

 we won't have to worry about interactions if we take an interrupt
 during the guest entry code.  While I don't see any obvious
 interactions, it could change in the future (e.g. it would be bad if
 the non-hv code were used on 64-bit or if 32-bit guest lazy  
interrupt

 disabling, since the non-hv code changes IVPR among other things).

Shouldn't the interrupts be marked soft-enabled (even if hard  
disabled)

when entering the guest ?

Ie. The last stage of entry will hard enable, so they should be
soft-enabled too... if not, latency trackers will consider the whole
guest periods as interrupt disabled...


OK... I guess we already have that problem on 32-bit as well?


Now, kvmppc_lazy_ee_enable() seems to be clearly bogus to me. It will
unconditionally set soft_enabled and clear irq_happened from a
soft-disabled state, thus potentially losing a pending event.

Book3S HV seems to be keeping interrupts fully enabled all the way
until the asm hard disables, which would be fine except that I'm  
worried

we are racy vs. need_resched  signals.

One thing you may be able to do is call prep_irq_for_idle(). This will
tell you if something happened, giving you a chance to abort/re-enable
before you go the guest.


As long as we go straight from IRQs fully enabled to hard-disabled,  
before we check for signals and such, I don't think we need that (and  
using it would raise the question of what to do on 32-bit).


What if we just take this patch, and add trace_hardirqs_on() just  
before entering the guest?  This would be similar to what the 32-bit  
non-KVM exception return code does (except it would be in C code).   
Perhaps we could set soft_enabled as well, but then we'd have to clear  
it again before calling kvmppc_restart_interrupt() -- since the KVM  
exception handlers don't actually care about soft_enabled (it would  
just be for consistency), I'd rather just leave soft_enabled off.


We also don't want PACA_IRQ_HARD_DIS to be cleared the way  
prep_irq_for_idle() does, because that's what lets the  
local_irq_enable() do the hard-enabling after we exit the guest.


-Scott
--
To unsubscribe from this list: send the line unsubscribe kvm-ppc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] kvm/ppc/booke64: Hard disable interrupts when entering the guest

2013-05-06 Thread Benjamin Herrenschmidt
On Mon, 2013-05-06 at 18:53 -0500, Scott Wood wrote:
 
  Ie. The last stage of entry will hard enable, so they should be
  soft-enabled too... if not, latency trackers will consider the whole
  guest periods as interrupt disabled...
 
 OK... I guess we already have that problem on 32-bit as well?

32-bit doesn't do lazy disable, so the situation is a lot easier there.

  Now, kvmppc_lazy_ee_enable() seems to be clearly bogus to me. It will
  unconditionally set soft_enabled and clear irq_happened from a
  soft-disabled state, thus potentially losing a pending event.
  
  Book3S HV seems to be keeping interrupts fully enabled all the way
  until the asm hard disables, which would be fine except that I'm  
  worried
  we are racy vs. need_resched  signals.
  
  One thing you may be able to do is call prep_irq_for_idle(). This will
  tell you if something happened, giving you a chance to abort/re-enable
  before you go the guest.
 
 As long as we go straight from IRQs fully enabled to hard-disabled,  
 before we check for signals and such, I don't think we need that (and  
 using it would raise the question of what to do on 32-bit).

Except that you have to mark them as soft enabled before you enter the
guest with interrupts on...

But yes, I see your point. If interrupts are fully enabled and you call
hard_irq_disable(), there should be no chance for anything to mess
around with irq_happened.

However if you set soft-enabled later on before the rfid that returns to
the guest and sets EE, you *must* also clear PACA_IRQ_HARD_DIS in
irq_happened. If you get that out of sync bad things will happen later
on...

To be sure all is well, you might want to
WARN_ON(get_paca()-irq_happened == PACA_IRQ_HARD_DIS); (with a comment
explaining why so).

Another problem is that hard_irq_disable() doesn't call
trace_hardirqs_off()... We might want to fix that:

static inline void hard_irq_disable(void)
{
__hard_irq_disable();
if (get_paca()-soft_enabled)
trace_hardirqs_off();
get_paca()-soft_enabled = 0;
get_paca()-irq_happened |= PACA_IRQ_HARD_DIS;
}

 What if we just take this patch, and add trace_hardirqs_on() just  
 before entering the guest?

You still want to set soft_enabled I'd say ... though I can see how you
may get away without it as long as you call trace_hardirqs_off() right
on the way back from the guest, but beware some lockdep bits will choke
if they ever spot the discrepancy between the traced irq state and
soft_enabled. I'd recommend you just keep it in sync.

   This would be similar to what the 32-bit  
 non-KVM exception return code does (except it would be in C code).   
 Perhaps we could set soft_enabled as well, but then we'd have to clear  
 it again before calling kvmppc_restart_interrupt() -- since the KVM  
 exception handlers don't actually care about soft_enabled (it would  
 just be for consistency), I'd rather just leave soft_enabled off.
 
 We also don't want PACA_IRQ_HARD_DIS to be cleared the way  
 prep_irq_for_idle() does, because that's what lets the  
 local_irq_enable() do the hard-enabling after we exit the guest.

Then set it again. Don't leave the kernel in a state where soft_enabled
is 1 and irq_happened is non-zero. It might work in the specific KVM
case we are looking at now because we know we are coming back via KVM
exit and putting things right again but it's fragile, somebody will come
back and break it, etc...

If necessary, create (or improve existing) helpers that do the right
state adjustement. The cost of a couple of byte stores is negligible,
I'd rather you make sure everything remains in sync at all times.

Cheers,
Ben.


--
To unsubscribe from this list: send the line unsubscribe kvm-ppc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] kvm/ppc/booke64: Hard disable interrupts when entering the guest

2013-05-06 Thread Scott Wood

On 05/06/2013 07:03:14 PM, Benjamin Herrenschmidt wrote:

On Mon, 2013-05-06 at 18:53 -0500, Scott Wood wrote:

  Ie. The last stage of entry will hard enable, so they should be
  soft-enabled too... if not, latency trackers will consider the  
whole

  guest periods as interrupt disabled...

 OK... I guess we already have that problem on 32-bit as well?

32-bit doesn't do lazy disable, so the situation is a lot easier  
there.


Right, but it still currently enters the guest with interrupts marked  
as disabled, so we'd have the same latency tracker issue.



Another problem is that hard_irq_disable() doesn't call
trace_hardirqs_off()... We might want to fix that:

static inline void hard_irq_disable(void)
{
__hard_irq_disable();
if (get_paca()-soft_enabled)
trace_hardirqs_off();
get_paca()-soft_enabled = 0;
get_paca()-irq_happened |= PACA_IRQ_HARD_DIS;
}


Is it possible there are places that assume the current behavior?


 We also don't want PACA_IRQ_HARD_DIS to be cleared the way
 prep_irq_for_idle() does, because that's what lets the
 local_irq_enable() do the hard-enabling after we exit the guest.

Then set it again. Don't leave the kernel in a state where  
soft_enabled

is 1 and irq_happened is non-zero. It might work in the specific KVM
case we are looking at now because we know we are coming back via KVM
exit and putting things right again but it's fragile, somebody will  
come

back and break it, etc...


KVM is a pretty special case -- at least on booke, it's required that  
all exits from guest state go through the KVM exception code.  I think  
it's less likely that that changes, than something breaks in the code  
to fix up lazy ee state (especially since we've already seen the latter  
happen).


I'll give it a shot, though.


If necessary, create (or improve existing) helpers that do the right
state adjustement. The cost of a couple of byte stores is negligible,
I'd rather you make sure everything remains in sync at all times.


My concern was mainly about complexity -- it seemed simpler to just say  
that the during guest execution, CPU is in a special state that is not  
visible to anything that cares about lazy EE.  The fact that EE can  
actually be *off* and we still take the interrupt supports its  
specialness. :-)


-Scott
--
To unsubscribe from this list: send the line unsubscribe kvm-ppc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] kvm/ppc/booke64: Hard disable interrupts when entering the guest

2013-05-06 Thread Benjamin Herrenschmidt
On Mon, 2013-05-06 at 22:05 -0500, Scott Wood wrote:
 On 05/06/2013 07:03:14 PM, Benjamin Herrenschmidt wrote:
  On Mon, 2013-05-06 at 18:53 -0500, Scott Wood wrote:
  
Ie. The last stage of entry will hard enable, so they should be
soft-enabled too... if not, latency trackers will consider the  
  whole
guest periods as interrupt disabled...
  
   OK... I guess we already have that problem on 32-bit as well?
  
  32-bit doesn't do lazy disable, so the situation is a lot easier  
  there.
 
 Right, but it still currently enters the guest with interrupts marked  
 as disabled, so we'd have the same latency tracker issue.
 
  Another problem is that hard_irq_disable() doesn't call
  trace_hardirqs_off()... We might want to fix that:
  
  static inline void hard_irq_disable(void)
  {
  __hard_irq_disable();
  if (get_paca()-soft_enabled)
  trace_hardirqs_off();
  get_paca()-soft_enabled = 0;
  get_paca()-irq_happened |= PACA_IRQ_HARD_DIS;
  }
 
 Is it possible there are places that assume the current behavior?

There aren't many callers, I think this should be safe. Most
callers call it with interrupts already soft disabled, so that
should be a nop in these cases (idle for example).

But I can give it a quick spin today on a machine or two.

   We also don't want PACA_IRQ_HARD_DIS to be cleared the way
   prep_irq_for_idle() does, because that's what lets the
   local_irq_enable() do the hard-enabling after we exit the guest.
  
  Then set it again. Don't leave the kernel in a state where  
  soft_enabled
  is 1 and irq_happened is non-zero. It might work in the specific KVM
  case we are looking at now because we know we are coming back via KVM
  exit and putting things right again but it's fragile, somebody will  
  come
  back and break it, etc...
 
 KVM is a pretty special case -- at least on booke, it's required that  
 all exits from guest state go through the KVM exception code.  I think  
 it's less likely that that changes, than something breaks in the code  
 to fix up lazy ee state (especially since we've already seen the latter  
 happen).
 
 I'll give it a shot, though.
 
  If necessary, create (or improve existing) helpers that do the right
  state adjustement. The cost of a couple of byte stores is negligible,
  I'd rather you make sure everything remains in sync at all times.
 
 My concern was mainly about complexity -- it seemed simpler to just say  
 that the during guest execution, CPU is in a special state that is not  
 visible to anything that cares about lazy EE.  The fact that EE can  
 actually be *off* and we still take the interrupt supports its  
 specialness. :-)

Yeah ... sort of :-)

Cheers,
Ben.


--
To unsubscribe from this list: send the line unsubscribe kvm-ppc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] kvm/ppc/booke64: Hard disable interrupts when entering the guest

2013-05-05 Thread Benjamin Herrenschmidt
On Fri, 2013-05-03 at 18:45 -0500, Scott Wood wrote:
 kvmppc_lazy_ee_enable() was causing interrupts to be soft-enabled
 (albeit hard-disabled) in kvmppc_restart_interrupt().  This led to
 warnings, and possibly breakage if the interrupt state was later saved
 and then restored (leading to interrupts being hard-and-soft enabled
 when they should be at least soft-disabled).
 
 Simply removing kvmppc_lazy_ee_enable() leaves interrupts only
 soft-disabled when we enter the guest, but they will be hard-disabled
 when we exit the guest -- without PACA_IRQ_HARD_DIS ever being set, so
 the local_irq_enable() fails to hard-enable.
 
 While we could just set PACA_IRQ_HARD_DIS after an exit to compensate,
 instead hard-disable interrupts before entering the guest.  This way,
 we won't have to worry about interactions if we take an interrupt
 during the guest entry code.  While I don't see any obvious
 interactions, it could change in the future (e.g. it would be bad if
 the non-hv code were used on 64-bit or if 32-bit guest lazy interrupt
 disabling, since the non-hv code changes IVPR among other things).

Shouldn't the interrupts be marked soft-enabled (even if hard disabled)
when entering the guest ?

Ie. The last stage of entry will hard enable, so they should be
soft-enabled too... if not, latency trackers will consider the whole
guest periods as interrupt disabled...

Now, kvmppc_lazy_ee_enable() seems to be clearly bogus to me. It will
unconditionally set soft_enabled and clear irq_happened from a
soft-disabled state, thus potentially losing a pending event.

Book3S HV seems to be keeping interrupts fully enabled all the way
until the asm hard disables, which would be fine except that I'm worried
we are racy vs. need_resched  signals.

One thing you may be able to do is call prep_irq_for_idle(). This will
tell you if something happened, giving you a chance to abort/re-enable
before you go the guest.

Ben.


--
To unsubscribe from this list: send the line unsubscribe kvm-ppc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH] kvm/ppc/booke64: Hard disable interrupts when entering the guest

2013-05-04 Thread Caraman Mihai Claudiu-B02008
 -Original Message-
 From: Wood Scott-B07421
 Sent: Saturday, May 04, 2013 2:45 AM
 To: Alexander Graf
 Cc: kvm-ppc@vger.kernel.org; k...@vger.kernel.org; linuxppc-
 d...@lists.ozlabs.org; Wood Scott-B07421; Caraman Mihai Claudiu-B02008
 Subject: [PATCH] kvm/ppc/booke64: Hard disable interrupts when entering
 the guest
 
 kvmppc_lazy_ee_enable() was causing interrupts to be soft-enabled
 (albeit hard-disabled) in kvmppc_restart_interrupt().  This led to
 warnings, and possibly breakage if the interrupt state was later saved
 and then restored (leading to interrupts being hard-and-soft enabled
 when they should be at least soft-disabled).
 
 Simply removing kvmppc_lazy_ee_enable() leaves interrupts only
 soft-disabled when we enter the guest, but they will be hard-disabled
 when we exit the guest -- without PACA_IRQ_HARD_DIS ever being set, so
 the local_irq_enable() fails to hard-enable.

Just to mention one special case. may_hard_irq_enable() called from do_IRQ()
and timer_interrupt() clears PACA_IRQ_HARD_DIS but it either hard-enable or 
let PACA_IRQ_EE set which is enough for local_irq_enable() to hard-enable.

 
 While we could just set PACA_IRQ_HARD_DIS after an exit to compensate,
 instead hard-disable interrupts before entering the guest.  This way,
 we won't have to worry about interactions if we take an interrupt
 during the guest entry code.  While I don't see any obvious
 interactions, it could change in the future (e.g. it would be bad if
 the non-hv code were used on 64-bit or if 32-bit guest lazy interrupt
 disabling, since the non-hv code changes IVPR among other things).
 
 Signed-off-by: Scott Wood scottw...@freescale.com
 Cc: Mihai Caraman mihai.cara...@freescale.com

Please add my signed-off, it builds on the same principle of interrupts
soft-disabled to fix warnings and irq_happened flags to force interrupts
hard-enabled ... and parts of the code ;)

-Mike

--
To unsubscribe from this list: send the line unsubscribe kvm-ppc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] kvm/ppc/booke64: Hard disable interrupts when entering the guest

2013-05-03 Thread Scott Wood
kvmppc_lazy_ee_enable() was causing interrupts to be soft-enabled
(albeit hard-disabled) in kvmppc_restart_interrupt().  This led to
warnings, and possibly breakage if the interrupt state was later saved
and then restored (leading to interrupts being hard-and-soft enabled
when they should be at least soft-disabled).

Simply removing kvmppc_lazy_ee_enable() leaves interrupts only
soft-disabled when we enter the guest, but they will be hard-disabled
when we exit the guest -- without PACA_IRQ_HARD_DIS ever being set, so
the local_irq_enable() fails to hard-enable.

While we could just set PACA_IRQ_HARD_DIS after an exit to compensate,
instead hard-disable interrupts before entering the guest.  This way,
we won't have to worry about interactions if we take an interrupt
during the guest entry code.  While I don't see any obvious
interactions, it could change in the future (e.g. it would be bad if
the non-hv code were used on 64-bit or if 32-bit guest lazy interrupt
disabling, since the non-hv code changes IVPR among other things).

Signed-off-by: Scott Wood scottw...@freescale.com
Cc: Mihai Caraman mihai.cara...@freescale.com
---
 arch/powerpc/kvm/booke.c |9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index ecbe908..b216821 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -666,14 +666,14 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct 
kvm_vcpu *vcpu)
return -EINVAL;
}
 
-   local_irq_disable();
+   hard_irq_disable();
+   trace_hardirqs_off();
s = kvmppc_prepare_to_enter(vcpu);
if (s = 0) {
local_irq_enable();
ret = s;
goto out;
}
-   kvmppc_lazy_ee_enable();
 
kvm_guest_enter();
 
@@ -1150,13 +1150,12 @@ int kvmppc_handle_exit(struct kvm_run *run, struct 
kvm_vcpu *vcpu,
 * aren't already exiting to userspace for some other reason.
 */
if (!(r  RESUME_HOST)) {
-   local_irq_disable();
+   hard_irq_disable();
+   trace_hardirqs_off();
s = kvmppc_prepare_to_enter(vcpu);
if (s = 0) {
local_irq_enable();
r = (s  2) | RESUME_HOST | (r  RESUME_FLAG_NV);
-   } else {
-   kvmppc_lazy_ee_enable();
}
}
 
-- 
1.7.10.4


--
To unsubscribe from this list: send the line unsubscribe kvm-ppc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] kvm/ppc/booke64: Hard disable interrupts when entering the guest

2013-05-03 Thread Scott Wood

On 05/03/2013 06:45:23 PM, Scott Wood wrote:

While we could just set PACA_IRQ_HARD_DIS after an exit to compensate,
instead hard-disable interrupts before entering the guest.  This way,
we won't have to worry about interactions if we take an interrupt
during the guest entry code.  While I don't see any obvious
interactions, it could change in the future (e.g. it would be bad if
the non-hv code were used on 64-bit or if 32-bit guest lazy interrupt
disabling, since the non-hv code changes IVPR among other things).


s/32-bit guest lazy/32-bit gets lazy/

-Scott
--
To unsubscribe from this list: send the line unsubscribe kvm-ppc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html