]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | Subject: Fix system calls on Cell entered with XER.SO=1 |
2 | From: Paul Mackerras <paulus@samba.org> | |
3 | References: 456406 - LTC50395 | |
4 | ||
5 | ||
6 | It turns out that on Cell, on a kernel with CONFIG_VIRT_CPU_ACCOUNTING=y, | |
7 | if a program sets the SO (summary overflow) bit in the XER and | |
8 | then does a system call, the SO bit in CR0 will be set on return | |
9 | regardless of whether the system call detected an error. Since CR0.SO | |
10 | is used as the error indication from the system call, this means that | |
11 | all system calls appear to fail. | |
12 | ||
13 | The reason is that the workaround for the timebase bug on Cell uses a | |
14 | compare instruction. With CONFIG_VIRT_CPU_ACCOUNTING = y, the | |
15 | ACCOUNT_CPU_USER_ENTRY macro reads the timebase, so we end up doing a | |
16 | compare instruction, which copies XER.SO to CR0.SO. Since we were | |
17 | doing this in the system call entry patch after clearing CR0.SO but | |
18 | before saving the CR, this meant that the saved CR image had CR0.SO | |
19 | set if XER.SO was set on entry. | |
20 | ||
21 | This fixes it by moving the clearing of CR0.SO to after the | |
22 | ACCOUNT_CPU_USER_ENTRY call in the system call entry path. | |
23 | ||
24 | Signed-off-by: Paul Mackerras <paulus@samba.org> | |
25 | Acked-by: Arnd Bergmann <arnd@arndb.de> | |
26 | Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> | |
27 | Signed-off-by: Olaf Hering <olh@suse.de> | |
28 | ||
29 | --- | |
30 | arch/powerpc/kernel/entry_64.S | 2 +- | |
31 | 1 file changed, 1 insertion(+), 1 deletion(-) | |
32 | ||
33 | --- a/arch/powerpc/kernel/entry_64.S | |
34 | +++ b/arch/powerpc/kernel/entry_64.S | |
35 | @@ -57,12 +57,12 @@ system_call_common: | |
36 | beq- 1f | |
37 | ld r1,PACAKSAVE(r13) | |
38 | 1: std r10,0(r1) | |
39 | - crclr so | |
40 | std r11,_NIP(r1) | |
41 | std r12,_MSR(r1) | |
42 | std r0,GPR0(r1) | |
43 | std r10,GPR1(r1) | |
44 | ACCOUNT_CPU_USER_ENTRY(r10, r11) | |
45 | + crclr so | |
46 | std r2,GPR2(r1) | |
47 | std r3,GPR3(r1) | |
48 | std r4,GPR4(r1) |