| From foo@baz Sun Apr 20 18:23:45 PDT 2014 |
| From: "David S. Miller" <davem@davemloft.net> |
| Date: Mon, 24 Mar 2014 14:45:12 -0400 |
| Subject: sparc64: Make sure %pil interrupts are enabled during hypervisor yield. |
| |
| From: "David S. Miller" <davem@davemloft.net> |
| |
| [ Upstream commit cb3042d609e30e6144024801c89be3925106752b ] |
| |
| In arch_cpu_idle() we must enable %pil based interrupts before |
| potentially invoking the hypervisor cpu yield call. |
| |
| As per the Hypervisor API documentation for cpu_yield: |
| |
| Interrupts which are blocked by some mechanism other that |
| pstate.ie (for example %pil) are not guaranteed to cause |
| a return from this service. |
| |
| It seems that only first generation Niagara chips are hit by this |
| bug. My best guess is that later chips implement this in hardware |
| and wake up anyways from %pil events, whereas in first generation |
| chips the yield is implemented completely in hypervisor code and |
| requires %pil to be enabled in order to wake properly from this |
| call. |
| |
| Fixes: 87fa05aeb3a5 ("sparc: Use generic idle loop") |
| Reported-by: Fabio M. Di Nitto <fabbione@fabbione.net> |
| Reported-by: Jan Engelhardt <jengelh@inai.de> |
| Tested-by: Jan Engelhardt <jengelh@inai.de> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/sparc/kernel/process_64.c | 4 +++- |
| 1 file changed, 3 insertions(+), 1 deletion(-) |
| |
| --- a/arch/sparc/kernel/process_64.c |
| +++ b/arch/sparc/kernel/process_64.c |
| @@ -57,9 +57,12 @@ void arch_cpu_idle(void) |
| { |
| if (tlb_type != hypervisor) { |
| touch_nmi_watchdog(); |
| + local_irq_enable(); |
| } else { |
| unsigned long pstate; |
| |
| + local_irq_enable(); |
| + |
| /* The sun4v sleeping code requires that we have PSTATE.IE cleared over |
| * the cpu sleep hypervisor call. |
| */ |
| @@ -81,7 +84,6 @@ void arch_cpu_idle(void) |
| : "=&r" (pstate) |
| : "i" (PSTATE_IE)); |
| } |
| - local_irq_enable(); |
| } |
| |
| #ifdef CONFIG_HOTPLUG_CPU |