aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/powerpc/transactional_memory.txt175
-rw-r--r--arch/powerpc/Kconfig8
-rw-r--r--arch/powerpc/configs/ppc64_defconfig2
-rw-r--r--arch/powerpc/configs/ps3_defconfig15
-rw-r--r--arch/powerpc/configs/pseries_defconfig2
-rw-r--r--arch/powerpc/include/asm/cputable.h10
-rw-r--r--arch/powerpc/include/asm/exception-64s.h92
-rw-r--r--arch/powerpc/include/asm/kvm_book3s_asm.h3
-rw-r--r--arch/powerpc/include/asm/kvm_host.h1
-rw-r--r--arch/powerpc/include/asm/paca.h4
-rw-r--r--arch/powerpc/include/asm/ppc-opcode.h10
-rw-r--r--arch/powerpc/include/asm/ppc_asm.h83
-rw-r--r--arch/powerpc/include/asm/processor.h29
-rw-r--r--arch/powerpc/include/asm/ps3.h2
-rw-r--r--arch/powerpc/include/asm/reg.h30
-rw-r--r--arch/powerpc/include/asm/tm.h20
-rw-r--r--arch/powerpc/kernel/Makefile2
-rw-r--r--arch/powerpc/kernel/asm-offsets.c29
-rw-r--r--arch/powerpc/kernel/entry_64.S4
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S184
-rw-r--r--arch/powerpc/kernel/fpu.S66
-rw-r--r--arch/powerpc/kernel/paca.c2
-rw-r--r--arch/powerpc/kernel/process.c135
-rw-r--r--arch/powerpc/kernel/setup_64.c18
-rw-r--r--arch/powerpc/kernel/signal.h8
-rw-r--r--arch/powerpc/kernel/signal_32.c500
-rw-r--r--arch/powerpc/kernel/signal_64.c337
-rw-r--r--arch/powerpc/kernel/tm.S388
-rw-r--r--arch/powerpc/kernel/traps.c144
-rw-r--r--arch/powerpc/kernel/vector.S51
-rw-r--r--arch/powerpc/kvm/book3s_hv_rmhandlers.S9
-rw-r--r--arch/powerpc/kvm/book3s_pr.c1
-rw-r--r--arch/powerpc/mm/hash_utils_64.c16
-rw-r--r--arch/powerpc/platforms/ps3/htab.c14
34 files changed, 2294 insertions, 100 deletions
diff --git a/Documentation/powerpc/transactional_memory.txt b/Documentation/powerpc/transactional_memory.txt
new file mode 100644
index 000000000000..c907be41d60f
--- /dev/null
+++ b/Documentation/powerpc/transactional_memory.txt
@@ -0,0 +1,175 @@
1Transactional Memory support
2============================
3
4POWER kernel support for this feature is currently limited to supporting
5its use by user programs. It is not currently used by the kernel itself.
6
7This file aims to sum up how it is supported by Linux and what behaviour you
8can expect from your user programs.
9
10
11Basic overview
12==============
13
14Hardware Transactional Memory is supported on POWER8 processors, and is a
15feature that enables a different form of atomic memory access. Several new
16instructions are presented to delimit transactions; transactions are
17guaranteed to either complete atomically or roll back and undo any partial
18changes.
19
20A simple transaction looks like this:
21
22begin_move_money:
23 tbegin
24 beq abort_handler
25
26 ld r4, SAVINGS_ACCT(r3)
27 ld r5, CURRENT_ACCT(r3)
28 subi r5, r5, 1
29 addi r4, r4, 1
30 std r4, SAVINGS_ACCT(r3)
31 std r5, CURRENT_ACCT(r3)
32
33 tend
34
35 b continue
36
37abort_handler:
38 ... test for odd failures ...
39
40 /* Retry the transaction if it failed because it conflicted with
41 * someone else: */
42 b begin_move_money
43
44
45The 'tbegin' instruction denotes the start point, and 'tend' the end point.
46Between these points the processor is in 'Transactional' state; any memory
47references will complete in one go if there are no conflicts with other
48transactional or non-transactional accesses within the system. In this
49example, the transaction completes as though it were normal straight-line code
50IF no other processor has touched SAVINGS_ACCT(r3) or CURRENT_ACCT(r3); an
51atomic move of money from the current account to the savings account has been
52performed. Even though the normal ld/std instructions are used (note no
53lwarx/stwcx), either *both* SAVINGS_ACCT(r3) and CURRENT_ACCT(r3) will be
54updated, or neither will be updated.
55
56If, in the meantime, there is a conflict with the locations accessed by the
57transaction, the transaction will be aborted by the CPU. Register and memory
58state will roll back to that at the 'tbegin', and control will continue from
59'tbegin+4'. The branch to abort_handler will be taken this second time; the
60abort handler can check the cause of the failure, and retry.
61
62Checkpointed registers include all GPRs, FPRs, VRs/VSRs, LR, CCR/CR, CTR, FPCSR
63and a few other status/flag regs; see the ISA for details.
64
65Causes of transaction aborts
66============================
67
68- Conflicts with cache lines used by other processors
69- Signals
70- Context switches
71- See the ISA for full documentation of everything that will abort transactions.
72
73
74Syscalls
75========
76
77Performing syscalls from within transaction is not recommended, and can lead
78to unpredictable results.
79
80Syscalls do not by design abort transactions, but beware: The kernel code will
81not be running in transactional state. The effect of syscalls will always
82remain visible, but depending on the call they may abort your transaction as a
83side-effect, read soon-to-be-aborted transactional data that should not remain
84invisible, etc. If you constantly retry a transaction that constantly aborts
85itself by calling a syscall, you'll have a livelock & make no progress.
86
87Simple syscalls (e.g. sigprocmask()) "could" be OK. Even things like write()
88from, say, printf() should be OK as long as the kernel does not access any
89memory that was accessed transactionally.
90
91Consider any syscalls that happen to work as debug-only -- not recommended for
92production use. Best to queue them up till after the transaction is over.
93
94
95Signals
96=======
97
98Delivery of signals (both sync and async) during transactions provides a second
99thread state (ucontext/mcontext) to represent the second transactional register
100state. Signal delivery 'treclaim's to capture both register states, so signals
101abort transactions. The usual ucontext_t passed to the signal handler
102represents the checkpointed/original register state; the signal appears to have
103arisen at 'tbegin+4'.
104
105If the sighandler ucontext has uc_link set, a second ucontext has been
106delivered. For future compatibility the MSR.TS field should be checked to
107determine the transactional state -- if so, the second ucontext in uc->uc_link
108represents the active transactional registers at the point of the signal.
109
110For 64-bit processes, uc->uc_mcontext.regs->msr is a full 64-bit MSR and its TS
111field shows the transactional mode.
112
113For 32-bit processes, the mcontext's MSR register is only 32 bits; the top 32
114bits are stored in the MSR of the second ucontext, i.e. in
115uc->uc_link->uc_mcontext.regs->msr. The top word contains the transactional
116state TS.
117
118However, basic signal handlers don't need to be aware of transactions
119and simply returning from the handler will deal with things correctly:
120
121Transaction-aware signal handlers can read the transactional register state
122from the second ucontext. This will be necessary for crash handlers to
123determine, for example, the address of the instruction causing the SIGSEGV.
124
125Example signal handler:
126
127 void crash_handler(int sig, siginfo_t *si, void *uc)
128 {
129 ucontext_t *ucp = uc;
130 ucontext_t *transactional_ucp = ucp->uc_link;
131
132 if (ucp_link) {
133 u64 msr = ucp->uc_mcontext.regs->msr;
134 /* May have transactional ucontext! */
135#ifndef __powerpc64__
136 msr |= ((u64)transactional_ucp->uc_mcontext.regs->msr) << 32;
137#endif
138 if (MSR_TM_ACTIVE(msr)) {
139 /* Yes, we crashed during a transaction. Oops. */
140 fprintf(stderr, "Transaction to be restarted at 0x%llx, but "
141 "crashy instruction was at 0x%llx\n",
142 ucp->uc_mcontext.regs->nip,
143 transactional_ucp->uc_mcontext.regs->nip);
144 }
145 }
146
147 fix_the_problem(ucp->dar);
148 }
149
150
151Failure cause codes used by kernel
152==================================
153
154These are defined in <asm/reg.h>, and distinguish different reasons why the
155kernel aborted a transaction:
156
157 TM_CAUSE_RESCHED Thread was rescheduled.
158 TM_CAUSE_FAC_UNAV FP/VEC/VSX unavailable trap.
159 TM_CAUSE_SYSCALL Currently unused; future syscalls that must abort
160 transactions for consistency will use this.
161 TM_CAUSE_SIGNAL Signal delivered.
162 TM_CAUSE_MISC Currently unused.
163
164These can be checked by the user program's abort handler as TEXASR[0:7].
165
166
167GDB
168===
169
170GDB and ptrace are not currently TM-aware. If one stops during a transaction,
171it looks like the transaction has just started (the checkpointed state is
172presented). The transaction cannot then be continued and will take the failure
173handler route. Furthermore, the transactional 2nd register state will be
174inaccessible. GDB can currently be used on programs using TM, but not sensibly
175in parts within transactions.
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 4b27edbdb799..85ff3a080360 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -313,6 +313,14 @@ config MATH_EMULATION
313 unit, which will allow programs that use floating-point 313 unit, which will allow programs that use floating-point
314 instructions to run. 314 instructions to run.
315 315
316config PPC_TRANSACTIONAL_MEM
317 bool "Transactional Memory support for POWERPC"
318 depends on PPC_BOOK3S_64
319 depends on SMP
320 default n
321 ---help---
322 Support user-mode Transactional Memory on POWERPC.
323
316config 8XX_MINIMAL_FPEMU 324config 8XX_MINIMAL_FPEMU
317 bool "Minimal math emulation for 8xx" 325 bool "Minimal math emulation for 8xx"
318 depends on 8xx && !MATH_EMULATION 326 depends on 8xx && !MATH_EMULATION
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index 6cbdeb4290e2..aef3f71de5ad 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -49,6 +49,8 @@ CONFIG_CPU_FREQ_GOV_USERSPACE=y
49CONFIG_CPU_FREQ_PMAC64=y 49CONFIG_CPU_FREQ_PMAC64=y
50CONFIG_HZ_100=y 50CONFIG_HZ_100=y
51CONFIG_BINFMT_MISC=m 51CONFIG_BINFMT_MISC=m
52CONFIG_PPC_TRANSACTIONAL_MEM=y
53CONFIG_HOTPLUG_CPU=y
52CONFIG_KEXEC=y 54CONFIG_KEXEC=y
53CONFIG_IRQ_ALL_CPUS=y 55CONFIG_IRQ_ALL_CPUS=y
54CONFIG_MEMORY_HOTREMOVE=y 56CONFIG_MEMORY_HOTREMOVE=y
diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig
index c2f4b4a86ece..7a5c15fcc7cf 100644
--- a/arch/powerpc/configs/ps3_defconfig
+++ b/arch/powerpc/configs/ps3_defconfig
@@ -6,6 +6,7 @@ CONFIG_NR_CPUS=2
6CONFIG_EXPERIMENTAL=y 6CONFIG_EXPERIMENTAL=y
7CONFIG_SYSVIPC=y 7CONFIG_SYSVIPC=y
8CONFIG_POSIX_MQUEUE=y 8CONFIG_POSIX_MQUEUE=y
9CONFIG_HIGH_RES_TIMERS=y
9CONFIG_BLK_DEV_INITRD=y 10CONFIG_BLK_DEV_INITRD=y
10CONFIG_CC_OPTIMIZE_FOR_SIZE=y 11CONFIG_CC_OPTIMIZE_FOR_SIZE=y
11CONFIG_EMBEDDED=y 12CONFIG_EMBEDDED=y
@@ -24,12 +25,13 @@ CONFIG_PS3_DISK=y
24CONFIG_PS3_ROM=y 25CONFIG_PS3_ROM=y
25CONFIG_PS3_FLASH=y 26CONFIG_PS3_FLASH=y
26CONFIG_PS3_VRAM=m 27CONFIG_PS3_VRAM=m
28CONFIG_PS3_LPM=m
27# CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set 29# CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set
28CONFIG_HIGH_RES_TIMERS=y
29# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set 30# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
30CONFIG_BINFMT_MISC=y 31CONFIG_BINFMT_MISC=y
31CONFIG_KEXEC=y 32CONFIG_KEXEC=y
32# CONFIG_SPARSEMEM_VMEMMAP is not set 33# CONFIG_SPARSEMEM_VMEMMAP is not set
34# CONFIG_COMPACTION is not set
33CONFIG_SCHED_SMT=y 35CONFIG_SCHED_SMT=y
34CONFIG_CMDLINE_BOOL=y 36CONFIG_CMDLINE_BOOL=y
35CONFIG_CMDLINE="" 37CONFIG_CMDLINE=""
@@ -59,6 +61,7 @@ CONFIG_BT_BNEP_PROTO_FILTER=y
59CONFIG_BT_HIDP=m 61CONFIG_BT_HIDP=m
60CONFIG_BT_HCIBTUSB=m 62CONFIG_BT_HCIBTUSB=m
61CONFIG_CFG80211=m 63CONFIG_CFG80211=m
64CONFIG_CFG80211_WEXT=y
62CONFIG_MAC80211=m 65CONFIG_MAC80211=m
63CONFIG_MAC80211_RC_PID=y 66CONFIG_MAC80211_RC_PID=y
64# CONFIG_MAC80211_RC_MINSTREL is not set 67# CONFIG_MAC80211_RC_MINSTREL is not set
@@ -78,7 +81,6 @@ CONFIG_MD=y
78CONFIG_BLK_DEV_DM=m 81CONFIG_BLK_DEV_DM=m
79CONFIG_NETDEVICES=y 82CONFIG_NETDEVICES=y
80# CONFIG_NET_VENDOR_BROADCOM is not set 83# CONFIG_NET_VENDOR_BROADCOM is not set
81# CONFIG_NET_VENDOR_CHELSIO is not set
82# CONFIG_NET_VENDOR_INTEL is not set 84# CONFIG_NET_VENDOR_INTEL is not set
83# CONFIG_NET_VENDOR_MARVELL is not set 85# CONFIG_NET_VENDOR_MARVELL is not set
84# CONFIG_NET_VENDOR_MICREL is not set 86# CONFIG_NET_VENDOR_MICREL is not set
@@ -119,21 +121,21 @@ CONFIG_SND=m
119# CONFIG_SND_DRIVERS is not set 121# CONFIG_SND_DRIVERS is not set
120CONFIG_SND_USB_AUDIO=m 122CONFIG_SND_USB_AUDIO=m
121CONFIG_HIDRAW=y 123CONFIG_HIDRAW=y
122CONFIG_USB_HIDDEV=y
123CONFIG_HID_APPLE=m 124CONFIG_HID_APPLE=m
124CONFIG_HID_BELKIN=m 125CONFIG_HID_BELKIN=m
125CONFIG_HID_CHERRY=m 126CONFIG_HID_CHERRY=m
126CONFIG_HID_EZKEY=m 127CONFIG_HID_EZKEY=m
127CONFIG_HID_TWINHAN=m 128CONFIG_HID_TWINHAN=m
128CONFIG_HID_LOGITECH=m 129CONFIG_HID_LOGITECH=m
130CONFIG_HID_LOGITECH_DJ=m
129CONFIG_HID_MICROSOFT=m 131CONFIG_HID_MICROSOFT=m
132CONFIG_HID_PS3REMOTE=m
130CONFIG_HID_SONY=m 133CONFIG_HID_SONY=m
131CONFIG_HID_SUNPLUS=m 134CONFIG_HID_SUNPLUS=m
132CONFIG_HID_SMARTJOYPLUS=m 135CONFIG_HID_SMARTJOYPLUS=m
136CONFIG_USB_HIDDEV=y
133CONFIG_USB=m 137CONFIG_USB=m
134CONFIG_USB_ANNOUNCE_NEW_DEVICES=y 138CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
135CONFIG_USB_DEVICEFS=y
136# CONFIG_USB_DEVICE_CLASS is not set
137CONFIG_USB_SUSPEND=y 139CONFIG_USB_SUSPEND=y
138CONFIG_USB_MON=m 140CONFIG_USB_MON=m
139CONFIG_USB_EHCI_HCD=m 141CONFIG_USB_EHCI_HCD=m
@@ -158,8 +160,8 @@ CONFIG_PROC_KCORE=y
158CONFIG_TMPFS=y 160CONFIG_TMPFS=y
159CONFIG_HUGETLBFS=y 161CONFIG_HUGETLBFS=y
160CONFIG_NFS_FS=y 162CONFIG_NFS_FS=y
161CONFIG_NFS_V3=y
162CONFIG_NFS_V4=y 163CONFIG_NFS_V4=y
164CONFIG_NFS_SWAP=y
163CONFIG_ROOT_NFS=y 165CONFIG_ROOT_NFS=y
164CONFIG_CIFS=m 166CONFIG_CIFS=m
165CONFIG_NLS=y 167CONFIG_NLS=y
@@ -176,6 +178,7 @@ CONFIG_DEBUG_INFO=y
176CONFIG_DEBUG_WRITECOUNT=y 178CONFIG_DEBUG_WRITECOUNT=y
177CONFIG_DEBUG_MEMORY_INIT=y 179CONFIG_DEBUG_MEMORY_INIT=y
178CONFIG_DEBUG_LIST=y 180CONFIG_DEBUG_LIST=y
181CONFIG_RCU_CPU_STALL_TIMEOUT=60
179# CONFIG_FTRACE is not set 182# CONFIG_FTRACE is not set
180CONFIG_DEBUG_STACKOVERFLOW=y 183CONFIG_DEBUG_STACKOVERFLOW=y
181CONFIG_CRYPTO_CCM=m 184CONFIG_CRYPTO_CCM=m
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
index 04fa7f2e295f..c4dfbaf8b192 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -43,6 +43,8 @@ CONFIG_RTAS_FLASH=m
43CONFIG_IBMEBUS=y 43CONFIG_IBMEBUS=y
44CONFIG_HZ_100=y 44CONFIG_HZ_100=y
45CONFIG_BINFMT_MISC=m 45CONFIG_BINFMT_MISC=m
46CONFIG_PPC_TRANSACTIONAL_MEM=y
47CONFIG_HOTPLUG_CPU=y
46CONFIG_KEXEC=y 48CONFIG_KEXEC=y
47CONFIG_IRQ_ALL_CPUS=y 49CONFIG_IRQ_ALL_CPUS=y
48CONFIG_MEMORY_HOTPLUG=y 50CONFIG_MEMORY_HOTPLUG=y
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index 5f1938fcce40..fb3245e928ea 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -220,6 +220,13 @@ extern const char *powerpc_base_platform;
220#define PPC_FEATURE_HAS_EFP_DOUBLE_COMP 0 220#define PPC_FEATURE_HAS_EFP_DOUBLE_COMP 0
221#endif 221#endif
222 222
223/* We only set the TM feature if the kernel was compiled with TM supprt */
224#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
225#define CPU_FTR_TM_COMP CPU_FTR_TM
226#else
227#define CPU_FTR_TM_COMP 0
228#endif
229
223/* We need to mark all pages as being coherent if we're SMP or we have a 230/* We need to mark all pages as being coherent if we're SMP or we have a
224 * 74[45]x and an MPC107 host bridge. Also 83xx and PowerQUICC II 231 * 74[45]x and an MPC107 host bridge. Also 83xx and PowerQUICC II
225 * require it for PCI "streaming/prefetch" to work properly. 232 * require it for PCI "streaming/prefetch" to work properly.
@@ -414,7 +421,8 @@ extern const char *powerpc_base_platform;
414 CPU_FTR_DSCR | CPU_FTR_SAO | \ 421 CPU_FTR_DSCR | CPU_FTR_SAO | \
415 CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ 422 CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
416 CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ 423 CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
417 CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | CPU_FTR_BCTAR) 424 CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | CPU_FTR_BCTAR | \
425 CPU_FTR_TM_COMP)
418#define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ 426#define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
419 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ 427 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
420 CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ 428 CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index 370298a0bca3..05e6d2ee1db9 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -50,7 +50,7 @@
50#define EX_PPR 88 /* SMT thread status register (priority) */ 50#define EX_PPR 88 /* SMT thread status register (priority) */
51 51
52#ifdef CONFIG_RELOCATABLE 52#ifdef CONFIG_RELOCATABLE
53#define EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) \ 53#define __EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) \
54 ld r12,PACAKBASE(r13); /* get high part of &label */ \ 54 ld r12,PACAKBASE(r13); /* get high part of &label */ \
55 mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \ 55 mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \
56 LOAD_HANDLER(r12,label); \ 56 LOAD_HANDLER(r12,label); \
@@ -61,13 +61,15 @@
61 blr; 61 blr;
62#else 62#else
63/* If not relocatable, we can jump directly -- and save messing with LR */ 63/* If not relocatable, we can jump directly -- and save messing with LR */
64#define EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) \ 64#define __EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) \
65 mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \ 65 mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \
66 mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \ 66 mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \
67 li r10,MSR_RI; \ 67 li r10,MSR_RI; \
68 mtmsrd r10,1; /* Set RI (EE=0) */ \ 68 mtmsrd r10,1; /* Set RI (EE=0) */ \
69 b label; 69 b label;
70#endif 70#endif
71#define EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) \
72 __EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) \
71 73
72/* 74/*
73 * As EXCEPTION_PROLOG_PSERIES(), except we've already got relocation on 75 * As EXCEPTION_PROLOG_PSERIES(), except we've already got relocation on
@@ -75,6 +77,7 @@
75 * case EXCEPTION_RELON_PROLOG_PSERIES_1 will be using lr. 77 * case EXCEPTION_RELON_PROLOG_PSERIES_1 will be using lr.
76 */ 78 */
77#define EXCEPTION_RELON_PROLOG_PSERIES(area, label, h, extra, vec) \ 79#define EXCEPTION_RELON_PROLOG_PSERIES(area, label, h, extra, vec) \
80 EXCEPTION_PROLOG_0(area); \
78 EXCEPTION_PROLOG_1(area, extra, vec); \ 81 EXCEPTION_PROLOG_1(area, extra, vec); \
79 EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) 82 EXCEPTION_RELON_PROLOG_PSERIES_1(label, h)
80 83
@@ -135,25 +138,32 @@ BEGIN_FTR_SECTION_NESTED(942) \
135END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,0,942) /*non P7*/ 138END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,0,942) /*non P7*/
136 139
137/* 140/*
138 * Save PPR in paca whenever some register is available to use. 141 * Get an SPR into a register if the CPU has the given feature
139 * Then increase the priority.
140 */ 142 */
141#define HMT_MEDIUM_PPR_SAVE(area, ra) \ 143#define OPT_GET_SPR(ra, spr, ftr) \
142BEGIN_FTR_SECTION_NESTED(943) \ 144BEGIN_FTR_SECTION_NESTED(943) \
143 mfspr ra,SPRN_PPR; \ 145 mfspr ra,spr; \
144 std ra,area+EX_PPR(r13); \ 146END_FTR_SECTION_NESTED(ftr,ftr,943)
145 HMT_MEDIUM; \
146END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,943)
147 147
148#define __EXCEPTION_PROLOG_1(area, extra, vec) \ 148/*
149 * Save a register to the PACA if the CPU has the given feature
150 */
151#define OPT_SAVE_REG_TO_PACA(offset, ra, ftr) \
152BEGIN_FTR_SECTION_NESTED(943) \
153 std ra,offset(r13); \
154END_FTR_SECTION_NESTED(ftr,ftr,943)
155
156#define EXCEPTION_PROLOG_0(area) \
149 GET_PACA(r13); \ 157 GET_PACA(r13); \
150 std r9,area+EX_R9(r13); /* save r9 */ \ 158 std r9,area+EX_R9(r13); /* save r9 */ \
151 HMT_MEDIUM_PPR_SAVE(area, r9); \ 159 OPT_GET_SPR(r9, SPRN_PPR, CPU_FTR_HAS_PPR); \
160 HMT_MEDIUM; \
152 std r10,area+EX_R10(r13); /* save r10 - r12 */ \ 161 std r10,area+EX_R10(r13); /* save r10 - r12 */ \
153 BEGIN_FTR_SECTION_NESTED(66); \ 162 OPT_GET_SPR(r10, SPRN_CFAR, CPU_FTR_CFAR)
154 mfspr r10,SPRN_CFAR; \ 163
155 std r10,area+EX_CFAR(r13); \ 164#define __EXCEPTION_PROLOG_1(area, extra, vec) \
156 END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66); \ 165 OPT_SAVE_REG_TO_PACA(area+EX_PPR, r9, CPU_FTR_HAS_PPR); \
166 OPT_SAVE_REG_TO_PACA(area+EX_CFAR, r10, CPU_FTR_CFAR); \
157 SAVE_LR(r10, area); \ 167 SAVE_LR(r10, area); \
158 mfcr r9; \ 168 mfcr r9; \
159 extra(vec); \ 169 extra(vec); \
@@ -178,6 +188,7 @@ END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,943)
178 __EXCEPTION_PROLOG_PSERIES_1(label, h) 188 __EXCEPTION_PROLOG_PSERIES_1(label, h)
179 189
180#define EXCEPTION_PROLOG_PSERIES(area, label, h, extra, vec) \ 190#define EXCEPTION_PROLOG_PSERIES(area, label, h, extra, vec) \
191 EXCEPTION_PROLOG_0(area); \
181 EXCEPTION_PROLOG_1(area, extra, vec); \ 192 EXCEPTION_PROLOG_1(area, extra, vec); \
182 EXCEPTION_PROLOG_PSERIES_1(label, h); 193 EXCEPTION_PROLOG_PSERIES_1(label, h);
183 194
@@ -188,10 +199,14 @@ END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,943)
188 199
189#define __KVM_HANDLER(area, h, n) \ 200#define __KVM_HANDLER(area, h, n) \
190do_kvm_##n: \ 201do_kvm_##n: \
202 BEGIN_FTR_SECTION_NESTED(947) \
203 ld r10,area+EX_CFAR(r13); \
204 std r10,HSTATE_CFAR(r13); \
205 END_FTR_SECTION_NESTED(CPU_FTR_CFAR,CPU_FTR_CFAR,947); \
191 ld r10,area+EX_R10(r13); \ 206 ld r10,area+EX_R10(r13); \
192 stw r9,HSTATE_SCRATCH1(r13); \ 207 stw r9,HSTATE_SCRATCH1(r13); \
193 ld r9,area+EX_R9(r13); \ 208 ld r9,area+EX_R9(r13); \
194 std r12,HSTATE_SCRATCH0(r13); \ 209 std r12,HSTATE_SCRATCH0(r13); \
195 li r12,n; \ 210 li r12,n; \
196 b kvmppc_interrupt 211 b kvmppc_interrupt
197 212
@@ -312,6 +327,13 @@ label##_pSeries: \
312 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, \ 327 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
313 EXC_STD, KVMTEST_PR, vec) 328 EXC_STD, KVMTEST_PR, vec)
314 329
330/* Version of above for when we have to branch out-of-line */
331#define STD_EXCEPTION_PSERIES_OOL(vec, label) \
332 .globl label##_pSeries; \
333label##_pSeries: \
334 EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_PR, vec); \
335 EXCEPTION_PROLOG_PSERIES_1(label##_common, EXC_STD)
336
315#define STD_EXCEPTION_HV(loc, vec, label) \ 337#define STD_EXCEPTION_HV(loc, vec, label) \
316 . = loc; \ 338 . = loc; \
317 .globl label##_hv; \ 339 .globl label##_hv; \
@@ -321,6 +343,13 @@ label##_hv: \
321 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, \ 343 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
322 EXC_HV, KVMTEST, vec) 344 EXC_HV, KVMTEST, vec)
323 345
346/* Version of above for when we have to branch out-of-line */
347#define STD_EXCEPTION_HV_OOL(vec, label) \
348 .globl label##_hv; \
349label##_hv: \
350 EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST, vec); \
351 EXCEPTION_PROLOG_PSERIES_1(label##_common, EXC_HV)
352
324#define STD_RELON_EXCEPTION_PSERIES(loc, vec, label) \ 353#define STD_RELON_EXCEPTION_PSERIES(loc, vec, label) \
325 . = loc; \ 354 . = loc; \
326 .globl label##_relon_pSeries; \ 355 .globl label##_relon_pSeries; \
@@ -331,6 +360,12 @@ label##_relon_pSeries: \
331 EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label##_common, \ 360 EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
332 EXC_STD, KVMTEST_PR, vec) 361 EXC_STD, KVMTEST_PR, vec)
333 362
363#define STD_RELON_EXCEPTION_PSERIES_OOL(vec, label) \
364 .globl label##_relon_pSeries; \
365label##_relon_pSeries: \
366 EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_PR, vec); \
367 EXCEPTION_RELON_PROLOG_PSERIES_1(label##_common, EXC_STD)
368
334#define STD_RELON_EXCEPTION_HV(loc, vec, label) \ 369#define STD_RELON_EXCEPTION_HV(loc, vec, label) \
335 . = loc; \ 370 . = loc; \
336 .globl label##_relon_hv; \ 371 .globl label##_relon_hv; \
@@ -341,6 +376,12 @@ label##_relon_hv: \
341 EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label##_common, \ 376 EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
342 EXC_HV, KVMTEST, vec) 377 EXC_HV, KVMTEST, vec)
343 378
379#define STD_RELON_EXCEPTION_HV_OOL(vec, label) \
380 .globl label##_relon_hv; \
381label##_relon_hv: \
382 EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST, vec); \
383 EXCEPTION_RELON_PROLOG_PSERIES_1(label##_common, EXC_HV)
384
344/* This associate vector numbers with bits in paca->irq_happened */ 385/* This associate vector numbers with bits in paca->irq_happened */
345#define SOFTEN_VALUE_0x500 PACA_IRQ_EE 386#define SOFTEN_VALUE_0x500 PACA_IRQ_EE
346#define SOFTEN_VALUE_0x502 PACA_IRQ_EE 387#define SOFTEN_VALUE_0x502 PACA_IRQ_EE
@@ -375,8 +416,10 @@ label##_relon_hv: \
375#define __MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra) \ 416#define __MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra) \
376 HMT_MEDIUM_PPR_DISCARD; \ 417 HMT_MEDIUM_PPR_DISCARD; \
377 SET_SCRATCH0(r13); /* save r13 */ \ 418 SET_SCRATCH0(r13); /* save r13 */ \
378 __EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec); \ 419 EXCEPTION_PROLOG_0(PACA_EXGEN); \
420 __EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec); \
379 EXCEPTION_PROLOG_PSERIES_1(label##_common, h); 421 EXCEPTION_PROLOG_PSERIES_1(label##_common, h);
422
380#define _MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra) \ 423#define _MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra) \
381 __MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra) 424 __MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra)
382 425
@@ -394,9 +437,16 @@ label##_hv: \
394 _MASKABLE_EXCEPTION_PSERIES(vec, label, \ 437 _MASKABLE_EXCEPTION_PSERIES(vec, label, \
395 EXC_HV, SOFTEN_TEST_HV) 438 EXC_HV, SOFTEN_TEST_HV)
396 439
440#define MASKABLE_EXCEPTION_HV_OOL(vec, label) \
441 .globl label##_hv; \
442label##_hv: \
443 EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_HV, vec); \
444 EXCEPTION_PROLOG_PSERIES_1(label##_common, EXC_HV);
445
397#define __MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, h, extra) \ 446#define __MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, h, extra) \
398 HMT_MEDIUM_PPR_DISCARD; \ 447 HMT_MEDIUM_PPR_DISCARD; \
399 SET_SCRATCH0(r13); /* save r13 */ \ 448 SET_SCRATCH0(r13); /* save r13 */ \
449 EXCEPTION_PROLOG_0(PACA_EXGEN); \
400 __EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec); \ 450 __EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec); \
401 EXCEPTION_RELON_PROLOG_PSERIES_1(label##_common, h); 451 EXCEPTION_RELON_PROLOG_PSERIES_1(label##_common, h);
402#define _MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, h, extra) \ 452#define _MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, h, extra) \
@@ -416,6 +466,12 @@ label##_relon_hv: \
416 _MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, \ 466 _MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, \
417 EXC_HV, SOFTEN_NOTEST_HV) 467 EXC_HV, SOFTEN_NOTEST_HV)
418 468
469#define MASKABLE_RELON_EXCEPTION_HV_OOL(vec, label) \
470 .globl label##_relon_hv; \
471label##_relon_hv: \
472 EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_NOTEST_HV, vec); \
473 EXCEPTION_PROLOG_PSERIES_1(label##_common, EXC_HV);
474
419/* 475/*
420 * Our exception common code can be passed various "additions" 476 * Our exception common code can be passed various "additions"
421 * to specify the behaviour of interrupts, whether to kick the 477 * to specify the behaviour of interrupts, whether to kick the
diff --git a/arch/powerpc/include/asm/kvm_book3s_asm.h b/arch/powerpc/include/asm/kvm_book3s_asm.h
index 88609b23b775..cdc3d2717cc6 100644
--- a/arch/powerpc/include/asm/kvm_book3s_asm.h
+++ b/arch/powerpc/include/asm/kvm_book3s_asm.h
@@ -93,6 +93,9 @@ struct kvmppc_host_state {
93 u64 host_dscr; 93 u64 host_dscr;
94 u64 dec_expires; 94 u64 dec_expires;
95#endif 95#endif
96#ifdef CONFIG_PPC_BOOK3S_64
97 u64 cfar;
98#endif
96}; 99};
97 100
98struct kvmppc_book3s_shadow_vcpu { 101struct kvmppc_book3s_shadow_vcpu {
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index ca9bf459db6a..03d7beae89a0 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -440,6 +440,7 @@ struct kvm_vcpu_arch {
440 ulong uamor; 440 ulong uamor;
441 u32 ctrl; 441 u32 ctrl;
442 ulong dabr; 442 ulong dabr;
443 ulong cfar;
443#endif 444#endif
444 u32 vrsave; /* also USPRG0 */ 445 u32 vrsave; /* also USPRG0 */
445 u32 mmucr; 446 u32 mmucr;
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index c47d687ab01b..77c91e74b612 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -137,6 +137,9 @@ struct paca_struct {
137 u8 irq_work_pending; /* IRQ_WORK interrupt while soft-disable */ 137 u8 irq_work_pending; /* IRQ_WORK interrupt while soft-disable */
138 u8 nap_state_lost; /* NV GPR values lost in power7_idle */ 138 u8 nap_state_lost; /* NV GPR values lost in power7_idle */
139 u64 sprg3; /* Saved user-visible sprg */ 139 u64 sprg3; /* Saved user-visible sprg */
140#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
141 u64 tm_scratch; /* TM scratch area for reclaim */
142#endif
140 143
141#ifdef CONFIG_PPC_POWERNV 144#ifdef CONFIG_PPC_POWERNV
142 /* Pointer to OPAL machine check event structure set by the 145 /* Pointer to OPAL machine check event structure set by the
@@ -167,7 +170,6 @@ struct paca_struct {
167}; 170};
168 171
169extern struct paca_struct *paca; 172extern struct paca_struct *paca;
170extern __initdata struct paca_struct boot_paca;
171extern void initialise_paca(struct paca_struct *new_paca, int cpu); 173extern void initialise_paca(struct paca_struct *new_paca, int cpu);
172extern void setup_paca(struct paca_struct *new_paca); 174extern void setup_paca(struct paca_struct *new_paca);
173extern void allocate_pacas(void); 175extern void allocate_pacas(void);
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
index 0fd1928efb93..8752bc8e34a3 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -129,6 +129,9 @@
129#define PPC_INST_TLBSRX_DOT 0x7c0006a5 129#define PPC_INST_TLBSRX_DOT 0x7c0006a5
130#define PPC_INST_XXLOR 0xf0000510 130#define PPC_INST_XXLOR 0xf0000510
131#define PPC_INST_XVCPSGNDP 0xf0000780 131#define PPC_INST_XVCPSGNDP 0xf0000780
132#define PPC_INST_TRECHKPT 0x7c0007dd
133#define PPC_INST_TRECLAIM 0x7c00075d
134#define PPC_INST_TABORT 0x7c00071d
132 135
133#define PPC_INST_NAP 0x4c000364 136#define PPC_INST_NAP 0x4c000364
134#define PPC_INST_SLEEP 0x4c0003a4 137#define PPC_INST_SLEEP 0x4c0003a4
@@ -294,4 +297,11 @@
294#define PPC_NAP stringify_in_c(.long PPC_INST_NAP) 297#define PPC_NAP stringify_in_c(.long PPC_INST_NAP)
295#define PPC_SLEEP stringify_in_c(.long PPC_INST_SLEEP) 298#define PPC_SLEEP stringify_in_c(.long PPC_INST_SLEEP)
296 299
300/* Transactional memory instructions */
301#define TRECHKPT stringify_in_c(.long PPC_INST_TRECHKPT)
302#define TRECLAIM(r) stringify_in_c(.long PPC_INST_TRECLAIM \
303 | __PPC_RA(r))
304#define TABORT(r) stringify_in_c(.long PPC_INST_TABORT \
305 | __PPC_RA(r))
306
297#endif /* _ASM_POWERPC_PPC_OPCODE_H */ 307#endif /* _ASM_POWERPC_PPC_OPCODE_H */
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
index c2d0e58aba31..54219cea9e88 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -123,6 +123,89 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR)
123#define REST_16VRS(n,b,base) REST_8VRS(n,b,base); REST_8VRS(n+8,b,base) 123#define REST_16VRS(n,b,base) REST_8VRS(n,b,base); REST_8VRS(n+8,b,base)
124#define REST_32VRS(n,b,base) REST_16VRS(n,b,base); REST_16VRS(n+16,b,base) 124#define REST_32VRS(n,b,base) REST_16VRS(n,b,base); REST_16VRS(n+16,b,base)
125 125
126/* Save/restore FPRs, VRs and VSRs from their checkpointed backups in
127 * thread_struct:
128 */
129#define SAVE_FPR_TRANSACT(n, base) stfd n,THREAD_TRANSACT_FPR0+ \
130 8*TS_FPRWIDTH*(n)(base)
131#define SAVE_2FPRS_TRANSACT(n, base) SAVE_FPR_TRANSACT(n, base); \
132 SAVE_FPR_TRANSACT(n+1, base)
133#define SAVE_4FPRS_TRANSACT(n, base) SAVE_2FPRS_TRANSACT(n, base); \
134 SAVE_2FPRS_TRANSACT(n+2, base)
135#define SAVE_8FPRS_TRANSACT(n, base) SAVE_4FPRS_TRANSACT(n, base); \
136 SAVE_4FPRS_TRANSACT(n+4, base)
137#define SAVE_16FPRS_TRANSACT(n, base) SAVE_8FPRS_TRANSACT(n, base); \
138 SAVE_8FPRS_TRANSACT(n+8, base)
139#define SAVE_32FPRS_TRANSACT(n, base) SAVE_16FPRS_TRANSACT(n, base); \
140 SAVE_16FPRS_TRANSACT(n+16, base)
141
142#define REST_FPR_TRANSACT(n, base) lfd n,THREAD_TRANSACT_FPR0+ \
143 8*TS_FPRWIDTH*(n)(base)
144#define REST_2FPRS_TRANSACT(n, base) REST_FPR_TRANSACT(n, base); \
145 REST_FPR_TRANSACT(n+1, base)
146#define REST_4FPRS_TRANSACT(n, base) REST_2FPRS_TRANSACT(n, base); \
147 REST_2FPRS_TRANSACT(n+2, base)
148#define REST_8FPRS_TRANSACT(n, base) REST_4FPRS_TRANSACT(n, base); \
149 REST_4FPRS_TRANSACT(n+4, base)
150#define REST_16FPRS_TRANSACT(n, base) REST_8FPRS_TRANSACT(n, base); \
151 REST_8FPRS_TRANSACT(n+8, base)
152#define REST_32FPRS_TRANSACT(n, base) REST_16FPRS_TRANSACT(n, base); \
153 REST_16FPRS_TRANSACT(n+16, base)
154
155
156#define SAVE_VR_TRANSACT(n,b,base) li b,THREAD_TRANSACT_VR0+(16*(n)); \
157 stvx n,b,base
158#define SAVE_2VRS_TRANSACT(n,b,base) SAVE_VR_TRANSACT(n,b,base); \
159 SAVE_VR_TRANSACT(n+1,b,base)
160#define SAVE_4VRS_TRANSACT(n,b,base) SAVE_2VRS_TRANSACT(n,b,base); \
161 SAVE_2VRS_TRANSACT(n+2,b,base)
162#define SAVE_8VRS_TRANSACT(n,b,base) SAVE_4VRS_TRANSACT(n,b,base); \
163 SAVE_4VRS_TRANSACT(n+4,b,base)
164#define SAVE_16VRS_TRANSACT(n,b,base) SAVE_8VRS_TRANSACT(n,b,base); \
165 SAVE_8VRS_TRANSACT(n+8,b,base)
166#define SAVE_32VRS_TRANSACT(n,b,base) SAVE_16VRS_TRANSACT(n,b,base); \
167 SAVE_16VRS_TRANSACT(n+16,b,base)
168
169#define REST_VR_TRANSACT(n,b,base) li b,THREAD_TRANSACT_VR0+(16*(n)); \
170 lvx n,b,base
171#define REST_2VRS_TRANSACT(n,b,base) REST_VR_TRANSACT(n,b,base); \
172 REST_VR_TRANSACT(n+1,b,base)
173#define REST_4VRS_TRANSACT(n,b,base) REST_2VRS_TRANSACT(n,b,base); \
174 REST_2VRS_TRANSACT(n+2,b,base)
175#define REST_8VRS_TRANSACT(n,b,base) REST_4VRS_TRANSACT(n,b,base); \
176 REST_4VRS_TRANSACT(n+4,b,base)
177#define REST_16VRS_TRANSACT(n,b,base) REST_8VRS_TRANSACT(n,b,base); \
178 REST_8VRS_TRANSACT(n+8,b,base)
179#define REST_32VRS_TRANSACT(n,b,base) REST_16VRS_TRANSACT(n,b,base); \
180 REST_16VRS_TRANSACT(n+16,b,base)
181
182
183#define SAVE_VSR_TRANSACT(n,b,base) li b,THREAD_TRANSACT_VSR0+(16*(n)); \
184 STXVD2X(n,R##base,R##b)
185#define SAVE_2VSRS_TRANSACT(n,b,base) SAVE_VSR_TRANSACT(n,b,base); \
186 SAVE_VSR_TRANSACT(n+1,b,base)
187#define SAVE_4VSRS_TRANSACT(n,b,base) SAVE_2VSRS_TRANSACT(n,b,base); \
188 SAVE_2VSRS_TRANSACT(n+2,b,base)
189#define SAVE_8VSRS_TRANSACT(n,b,base) SAVE_4VSRS_TRANSACT(n,b,base); \
190 SAVE_4VSRS_TRANSACT(n+4,b,base)
191#define SAVE_16VSRS_TRANSACT(n,b,base) SAVE_8VSRS_TRANSACT(n,b,base); \
192 SAVE_8VSRS_TRANSACT(n+8,b,base)
193#define SAVE_32VSRS_TRANSACT(n,b,base) SAVE_16VSRS_TRANSACT(n,b,base); \
194 SAVE_16VSRS_TRANSACT(n+16,b,base)
195
196#define REST_VSR_TRANSACT(n,b,base) li b,THREAD_TRANSACT_VSR0+(16*(n)); \
197 LXVD2X(n,R##base,R##b)
198#define REST_2VSRS_TRANSACT(n,b,base) REST_VSR_TRANSACT(n,b,base); \
199 REST_VSR_TRANSACT(n+1,b,base)
200#define REST_4VSRS_TRANSACT(n,b,base) REST_2VSRS_TRANSACT(n,b,base); \
201 REST_2VSRS_TRANSACT(n+2,b,base)
202#define REST_8VSRS_TRANSACT(n,b,base) REST_4VSRS_TRANSACT(n,b,base); \
203 REST_4VSRS_TRANSACT(n+4,b,base)
204#define REST_16VSRS_TRANSACT(n,b,base) REST_8VSRS_TRANSACT(n,b,base); \
205 REST_8VSRS_TRANSACT(n+8,b,base)
206#define REST_32VSRS_TRANSACT(n,b,base) REST_16VSRS_TRANSACT(n,b,base); \
207 REST_16VSRS_TRANSACT(n+16,b,base)
208
126/* Save the lower 32 VSRs in the thread VSR region */ 209/* Save the lower 32 VSRs in the thread VSR region */
127#define SAVE_VSR(n,b,base) li b,THREAD_VSR0+(16*(n)); STXVD2X(n,R##base,R##b) 210#define SAVE_VSR(n,b,base) li b,THREAD_VSR0+(16*(n)); STXVD2X(n,R##base,R##b)
128#define SAVE_2VSRS(n,b,base) SAVE_VSR(n,b,base); SAVE_VSR(n+1,b,base) 211#define SAVE_2VSRS(n,b,base) SAVE_VSR(n,b,base); SAVE_VSR(n+1,b,base)
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 42ac53cebacd..7ff9eaa3ea6c 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -152,6 +152,7 @@ typedef struct {
152#define TS_FPROFFSET 0 152#define TS_FPROFFSET 0
153#define TS_VSRLOWOFFSET 1 153#define TS_VSRLOWOFFSET 1
154#define TS_FPR(i) fpr[i][TS_FPROFFSET] 154#define TS_FPR(i) fpr[i][TS_FPROFFSET]
155#define TS_TRANS_FPR(i) transact_fpr[i][TS_FPROFFSET]
155 156
156struct thread_struct { 157struct thread_struct {
157 unsigned long ksp; /* Kernel stack pointer */ 158 unsigned long ksp; /* Kernel stack pointer */
@@ -246,6 +247,34 @@ struct thread_struct {
246 unsigned long spefscr; /* SPE & eFP status */ 247 unsigned long spefscr; /* SPE & eFP status */
247 int used_spe; /* set if process has used spe */ 248 int used_spe; /* set if process has used spe */
248#endif /* CONFIG_SPE */ 249#endif /* CONFIG_SPE */
250#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
251 u64 tm_tfhar; /* Transaction fail handler addr */
252 u64 tm_texasr; /* Transaction exception & summary */
253 u64 tm_tfiar; /* Transaction fail instr address reg */
254 unsigned long tm_orig_msr; /* Thread's MSR on ctx switch */
255 struct pt_regs ckpt_regs; /* Checkpointed registers */
256
257 /*
258 * Transactional FP and VSX 0-31 register set.
259 * NOTE: the sense of these is the opposite of the integer ckpt_regs!
260 *
261 * When a transaction is active/signalled/scheduled etc., *regs is the
262 * most recent set of/speculated GPRs with ckpt_regs being the older
263 * checkpointed regs to which we roll back if transaction aborts.
264 *
265 * However, fpr[] is the checkpointed 'base state' of FP regs, and
266 * transact_fpr[] is the new set of transactional values.
267 * VRs work the same way.
268 */
269 double transact_fpr[32][TS_FPRWIDTH];
270 struct {
271 unsigned int pad;
272 unsigned int val; /* Floating point status */
273 } transact_fpscr;
274 vector128 transact_vr[32] __attribute__((aligned(16)));
275 vector128 transact_vscr __attribute__((aligned(16)));
276 unsigned long transact_vrsave;
277#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
249#ifdef CONFIG_KVM_BOOK3S_32_HANDLER 278#ifdef CONFIG_KVM_BOOK3S_32_HANDLER
250 void* kvm_shadow_vcpu; /* KVM internal data */ 279 void* kvm_shadow_vcpu; /* KVM internal data */
251#endif /* CONFIG_KVM_BOOK3S_32_HANDLER */ 280#endif /* CONFIG_KVM_BOOK3S_32_HANDLER */
diff --git a/arch/powerpc/include/asm/ps3.h b/arch/powerpc/include/asm/ps3.h
index 0e15db4d703b..678a7c1d9cb8 100644
--- a/arch/powerpc/include/asm/ps3.h
+++ b/arch/powerpc/include/asm/ps3.h
@@ -245,7 +245,7 @@ enum lv1_result {
245 245
246static inline const char* ps3_result(int result) 246static inline const char* ps3_result(int result)
247{ 247{
248#if defined(DEBUG) 248#if defined(DEBUG) || defined(PS3_VERBOSE_RESULT)
249 switch (result) { 249 switch (result) {
250 case LV1_SUCCESS: 250 case LV1_SUCCESS:
251 return "LV1_SUCCESS (0)"; 251 return "LV1_SUCCESS (0)";
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index e09ac51961d7..7035e608f3fa 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -29,6 +29,10 @@
29#define MSR_SF_LG 63 /* Enable 64 bit mode */ 29#define MSR_SF_LG 63 /* Enable 64 bit mode */
30#define MSR_ISF_LG 61 /* Interrupt 64b mode valid on 630 */ 30#define MSR_ISF_LG 61 /* Interrupt 64b mode valid on 630 */
31#define MSR_HV_LG 60 /* Hypervisor state */ 31#define MSR_HV_LG 60 /* Hypervisor state */
32#define MSR_TS_T_LG 34 /* Trans Mem state: Transactional */
33#define MSR_TS_S_LG 33 /* Trans Mem state: Suspended */
34#define MSR_TS_LG 33 /* Trans Mem state (2 bits) */
35#define MSR_TM_LG 32 /* Trans Mem Available */
32#define MSR_VEC_LG 25 /* Enable AltiVec */ 36#define MSR_VEC_LG 25 /* Enable AltiVec */
33#define MSR_VSX_LG 23 /* Enable VSX */ 37#define MSR_VSX_LG 23 /* Enable VSX */
34#define MSR_POW_LG 18 /* Enable Power Management */ 38#define MSR_POW_LG 18 /* Enable Power Management */
@@ -98,6 +102,26 @@
98#define MSR_RI __MASK(MSR_RI_LG) /* Recoverable Exception */ 102#define MSR_RI __MASK(MSR_RI_LG) /* Recoverable Exception */
99#define MSR_LE __MASK(MSR_LE_LG) /* Little Endian */ 103#define MSR_LE __MASK(MSR_LE_LG) /* Little Endian */
100 104
105#define MSR_TM __MASK(MSR_TM_LG) /* Transactional Mem Available */
106#define MSR_TS_N 0 /* Non-transactional */
107#define MSR_TS_S __MASK(MSR_TS_S_LG) /* Transaction Suspended */
108#define MSR_TS_T __MASK(MSR_TS_T_LG) /* Transaction Transactional */
109#define MSR_TS_MASK (MSR_TS_T | MSR_TS_S) /* Transaction State bits */
110#define MSR_TM_ACTIVE(x) (((x) & MSR_TS_MASK) != 0) /* Transaction active? */
111#define MSR_TM_TRANSACTIONAL(x) (((x) & MSR_TS_MASK) == MSR_TS_T)
112#define MSR_TM_SUSPENDED(x) (((x) & MSR_TS_MASK) == MSR_TS_S)
113
114/* Reason codes describing kernel causes for transaction aborts. By
115 convention, bit0 is copied to TEXASR[56] (IBM bit 7) which is set if
116 the failure is persistent.
117*/
118#define TM_CAUSE_RESCHED 0xfe
119#define TM_CAUSE_TLBI 0xfc
120#define TM_CAUSE_FAC_UNAV 0xfa
121#define TM_CAUSE_SYSCALL 0xf9 /* Persistent */
122#define TM_CAUSE_MISC 0xf6
123#define TM_CAUSE_SIGNAL 0xf4
124
101#if defined(CONFIG_PPC_BOOK3S_64) 125#if defined(CONFIG_PPC_BOOK3S_64)
102#define MSR_64BIT MSR_SF 126#define MSR_64BIT MSR_SF
103 127
@@ -193,6 +217,10 @@
193#define SPRN_UAMOR 0x9d /* User Authority Mask Override Register */ 217#define SPRN_UAMOR 0x9d /* User Authority Mask Override Register */
194#define SPRN_AMOR 0x15d /* Authority Mask Override Register */ 218#define SPRN_AMOR 0x15d /* Authority Mask Override Register */
195#define SPRN_ACOP 0x1F /* Available Coprocessor Register */ 219#define SPRN_ACOP 0x1F /* Available Coprocessor Register */
220#define SPRN_TFIAR 0x81 /* Transaction Failure Inst Addr */
221#define SPRN_TEXASR 0x82 /* Transaction EXception & Summary */
222#define SPRN_TEXASRU 0x83 /* '' '' '' Upper 32 */
223#define SPRN_TFHAR 0x80 /* Transaction Failure Handler Addr */
196#define SPRN_CTRLF 0x088 224#define SPRN_CTRLF 0x088
197#define SPRN_CTRLT 0x098 225#define SPRN_CTRLT 0x098
198#define CTRL_CT 0xc0000000 /* current thread */ 226#define CTRL_CT 0xc0000000 /* current thread */
@@ -770,7 +798,7 @@
770 * HV mode in which case it is HSPRG0 798 * HV mode in which case it is HSPRG0
771 * 799 *
772 * 64-bit server: 800 * 64-bit server:
773 * - SPRG0 unused (reserved for HV on Power4) 801 * - SPRG0 scratch for TM recheckpoint/reclaim (reserved for HV on Power4)
774 * - SPRG2 scratch for exception vectors 802 * - SPRG2 scratch for exception vectors
775 * - SPRG3 CPU and NUMA node for VDSO getcpu (user visible) 803 * - SPRG3 CPU and NUMA node for VDSO getcpu (user visible)
776 * - HSPRG0 stores PACA in HV mode 804 * - HSPRG0 stores PACA in HV mode
diff --git a/arch/powerpc/include/asm/tm.h b/arch/powerpc/include/asm/tm.h
new file mode 100644
index 000000000000..4b4449abf3f8
--- /dev/null
+++ b/arch/powerpc/include/asm/tm.h
@@ -0,0 +1,20 @@
1/*
2 * Transactional memory support routines to reclaim and recheckpoint
3 * transactional process state.
4 *
5 * Copyright 2012 Matt Evans & Michael Neuling, IBM Corporation.
6 */
7
8#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
9extern void do_load_up_transact_fpu(struct thread_struct *thread);
10extern void do_load_up_transact_altivec(struct thread_struct *thread);
11#endif
12
13extern void tm_enable(void);
14extern void tm_reclaim(struct thread_struct *thread,
15 unsigned long orig_msr, uint8_t cause);
16extern void tm_recheckpoint(struct thread_struct *thread,
17 unsigned long orig_msr);
18extern void tm_abort(uint8_t cause);
19extern void tm_save_sprs(struct thread_struct *thread);
20extern void tm_restore_sprs(struct thread_struct *thread);
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index b4f0e360e414..f960a7944553 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -121,6 +121,8 @@ ifneq ($(CONFIG_PPC_INDIRECT_IO),y)
121obj-y += iomap.o 121obj-y += iomap.o
122endif 122endif
123 123
124obj64-$(CONFIG_PPC_TRANSACTIONAL_MEM) += tm.o
125
124obj-$(CONFIG_PPC64) += $(obj64-y) 126obj-$(CONFIG_PPC64) += $(obj64-y)
125obj-$(CONFIG_PPC32) += $(obj32-y) 127obj-$(CONFIG_PPC32) += $(obj32-y)
126 128
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index beddba432518..781190367292 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -125,6 +125,30 @@ int main(void)
125#ifdef CONFIG_PPC_BOOK3S_64 125#ifdef CONFIG_PPC_BOOK3S_64
126 DEFINE(THREAD_TAR, offsetof(struct thread_struct, tar)); 126 DEFINE(THREAD_TAR, offsetof(struct thread_struct, tar));
127#endif 127#endif
128#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
129 DEFINE(PACATMSCRATCH, offsetof(struct paca_struct, tm_scratch));
130 DEFINE(THREAD_TM_TFHAR, offsetof(struct thread_struct, tm_tfhar));
131 DEFINE(THREAD_TM_TEXASR, offsetof(struct thread_struct, tm_texasr));
132 DEFINE(THREAD_TM_TFIAR, offsetof(struct thread_struct, tm_tfiar));
133 DEFINE(PT_CKPT_REGS, offsetof(struct thread_struct, ckpt_regs));
134 DEFINE(THREAD_TRANSACT_VR0, offsetof(struct thread_struct,
135 transact_vr[0]));
136 DEFINE(THREAD_TRANSACT_VSCR, offsetof(struct thread_struct,
137 transact_vscr));
138 DEFINE(THREAD_TRANSACT_VRSAVE, offsetof(struct thread_struct,
139 transact_vrsave));
140 DEFINE(THREAD_TRANSACT_FPR0, offsetof(struct thread_struct,
141 transact_fpr[0]));
142 DEFINE(THREAD_TRANSACT_FPSCR, offsetof(struct thread_struct,
143 transact_fpscr));
144#ifdef CONFIG_VSX
145 DEFINE(THREAD_TRANSACT_VSR0, offsetof(struct thread_struct,
146 transact_fpr[0]));
147#endif
148 /* Local pt_regs on stack for Transactional Memory funcs. */
149 DEFINE(TM_FRAME_SIZE, STACK_FRAME_OVERHEAD +
150 sizeof(struct pt_regs) + 16);
151#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
128 152
129 DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); 153 DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
130 DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags)); 154 DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags));
@@ -479,6 +503,7 @@ int main(void)
479 DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst)); 503 DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
480 DEFINE(VCPU_TRAP, offsetof(struct kvm_vcpu, arch.trap)); 504 DEFINE(VCPU_TRAP, offsetof(struct kvm_vcpu, arch.trap));
481 DEFINE(VCPU_PTID, offsetof(struct kvm_vcpu, arch.ptid)); 505 DEFINE(VCPU_PTID, offsetof(struct kvm_vcpu, arch.ptid));
506 DEFINE(VCPU_CFAR, offsetof(struct kvm_vcpu, arch.cfar));
482 DEFINE(VCORE_ENTRY_EXIT, offsetof(struct kvmppc_vcore, entry_exit_count)); 507 DEFINE(VCORE_ENTRY_EXIT, offsetof(struct kvmppc_vcore, entry_exit_count));
483 DEFINE(VCORE_NAP_COUNT, offsetof(struct kvmppc_vcore, nap_count)); 508 DEFINE(VCORE_NAP_COUNT, offsetof(struct kvmppc_vcore, nap_count));
484 DEFINE(VCORE_IN_GUEST, offsetof(struct kvmppc_vcore, in_guest)); 509 DEFINE(VCORE_IN_GUEST, offsetof(struct kvmppc_vcore, in_guest));
@@ -558,6 +583,10 @@ int main(void)
558 DEFINE(IPI_PRIORITY, IPI_PRIORITY); 583 DEFINE(IPI_PRIORITY, IPI_PRIORITY);
559#endif /* CONFIG_KVM_BOOK3S_64_HV */ 584#endif /* CONFIG_KVM_BOOK3S_64_HV */
560 585
586#ifdef CONFIG_PPC_BOOK3S_64
587 HSTATE_FIELD(HSTATE_CFAR, cfar);
588#endif /* CONFIG_PPC_BOOK3S_64 */
589
561#else /* CONFIG_PPC_BOOK3S */ 590#else /* CONFIG_PPC_BOOK3S */
562 DEFINE(VCPU_CR, offsetof(struct kvm_vcpu, arch.cr)); 591 DEFINE(VCPU_CR, offsetof(struct kvm_vcpu, arch.cr));
563 DEFINE(VCPU_XER, offsetof(struct kvm_vcpu, arch.xer)); 592 DEFINE(VCPU_XER, offsetof(struct kvm_vcpu, arch.xer));
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 9ae8451bbc83..612ea130c5d2 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -785,6 +785,10 @@ fast_exception_return:
785 andc r4,r4,r0 /* r0 contains MSR_RI here */ 785 andc r4,r4,r0 /* r0 contains MSR_RI here */
786 mtmsrd r4,1 786 mtmsrd r4,1
787 787
788#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
789 /* TM debug */
790 std r3, PACATMSCRATCH(r13) /* Stash returned-to MSR */
791#endif
788 /* 792 /*
789 * r13 is our per cpu area, only restore it if we are returning to 793 * r13 is our per cpu area, only restore it if we are returning to
790 * userspace the value stored in the stack frame may belong to 794 * userspace the value stored in the stack frame may belong to
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 7a1c87cbb890..a8a5361fb70c 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -153,7 +153,10 @@ machine_check_pSeries_1:
153 * some code path might still want to branch into the original 153 * some code path might still want to branch into the original
154 * vector 154 * vector
155 */ 155 */
156 b machine_check_pSeries 156 HMT_MEDIUM_PPR_DISCARD
157 SET_SCRATCH0(r13) /* save r13 */
158 EXCEPTION_PROLOG_0(PACA_EXMC)
159 b machine_check_pSeries_0
157 160
158 . = 0x300 161 . = 0x300
159 .globl data_access_pSeries 162 .globl data_access_pSeries
@@ -172,6 +175,7 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_SLB)
172data_access_slb_pSeries: 175data_access_slb_pSeries:
173 HMT_MEDIUM_PPR_DISCARD 176 HMT_MEDIUM_PPR_DISCARD
174 SET_SCRATCH0(r13) 177 SET_SCRATCH0(r13)
178 EXCEPTION_PROLOG_0(PACA_EXSLB)
175 EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST, 0x380) 179 EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST, 0x380)
176 std r3,PACA_EXSLB+EX_R3(r13) 180 std r3,PACA_EXSLB+EX_R3(r13)
177 mfspr r3,SPRN_DAR 181 mfspr r3,SPRN_DAR
@@ -203,6 +207,7 @@ data_access_slb_pSeries:
203instruction_access_slb_pSeries: 207instruction_access_slb_pSeries:
204 HMT_MEDIUM_PPR_DISCARD 208 HMT_MEDIUM_PPR_DISCARD
205 SET_SCRATCH0(r13) 209 SET_SCRATCH0(r13)
210 EXCEPTION_PROLOG_0(PACA_EXSLB)
206 EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST_PR, 0x480) 211 EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST_PR, 0x480)
207 std r3,PACA_EXSLB+EX_R3(r13) 212 std r3,PACA_EXSLB+EX_R3(r13)
208 mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */ 213 mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */
@@ -284,16 +289,28 @@ system_call_pSeries:
284 */ 289 */
285 . = 0xe00 290 . = 0xe00
286hv_exception_trampoline: 291hv_exception_trampoline:
292 SET_SCRATCH0(r13)
293 EXCEPTION_PROLOG_0(PACA_EXGEN)
287 b h_data_storage_hv 294 b h_data_storage_hv
295
288 . = 0xe20 296 . = 0xe20
297 SET_SCRATCH0(r13)
298 EXCEPTION_PROLOG_0(PACA_EXGEN)
289 b h_instr_storage_hv 299 b h_instr_storage_hv
300
290 . = 0xe40 301 . = 0xe40
302 SET_SCRATCH0(r13)
303 EXCEPTION_PROLOG_0(PACA_EXGEN)
291 b emulation_assist_hv 304 b emulation_assist_hv
292 . = 0xe50 305
293 b hmi_exception_hv
294 . = 0xe60 306 . = 0xe60
307 SET_SCRATCH0(r13)
308 EXCEPTION_PROLOG_0(PACA_EXGEN)
295 b hmi_exception_hv 309 b hmi_exception_hv
310
296 . = 0xe80 311 . = 0xe80
312 SET_SCRATCH0(r13)
313 EXCEPTION_PROLOG_0(PACA_EXGEN)
297 b h_doorbell_hv 314 b h_doorbell_hv
298 315
299 /* We need to deal with the Altivec unavailable exception 316 /* We need to deal with the Altivec unavailable exception
@@ -303,16 +320,27 @@ hv_exception_trampoline:
303 */ 320 */
304performance_monitor_pSeries_1: 321performance_monitor_pSeries_1:
305 . = 0xf00 322 . = 0xf00
323 SET_SCRATCH0(r13)
324 EXCEPTION_PROLOG_0(PACA_EXGEN)
306 b performance_monitor_pSeries 325 b performance_monitor_pSeries
307 326
308altivec_unavailable_pSeries_1: 327altivec_unavailable_pSeries_1:
309 . = 0xf20 328 . = 0xf20
329 SET_SCRATCH0(r13)
330 EXCEPTION_PROLOG_0(PACA_EXGEN)
310 b altivec_unavailable_pSeries 331 b altivec_unavailable_pSeries
311 332
312vsx_unavailable_pSeries_1: 333vsx_unavailable_pSeries_1:
313 . = 0xf40 334 . = 0xf40
335 SET_SCRATCH0(r13)
336 EXCEPTION_PROLOG_0(PACA_EXGEN)
314 b vsx_unavailable_pSeries 337 b vsx_unavailable_pSeries
315 338
339 . = 0xf60
340 SET_SCRATCH0(r13)
341 EXCEPTION_PROLOG_0(PACA_EXGEN)
342 b tm_unavailable_pSeries
343
316#ifdef CONFIG_CBE_RAS 344#ifdef CONFIG_CBE_RAS
317 STD_EXCEPTION_HV(0x1200, 0x1202, cbe_system_error) 345 STD_EXCEPTION_HV(0x1200, 0x1202, cbe_system_error)
318 KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1202) 346 KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1202)
@@ -326,10 +354,7 @@ vsx_unavailable_pSeries_1:
326denorm_exception_hv: 354denorm_exception_hv:
327 HMT_MEDIUM_PPR_DISCARD 355 HMT_MEDIUM_PPR_DISCARD
328 mtspr SPRN_SPRG_HSCRATCH0,r13 356 mtspr SPRN_SPRG_HSCRATCH0,r13
329 mfspr r13,SPRN_SPRG_HPACA 357 EXCEPTION_PROLOG_0(PACA_EXGEN)
330 std r9,PACA_EXGEN+EX_R9(r13)
331 HMT_MEDIUM_PPR_SAVE(PACA_EXGEN, r9)
332 std r10,PACA_EXGEN+EX_R10(r13)
333 std r11,PACA_EXGEN+EX_R11(r13) 358 std r11,PACA_EXGEN+EX_R11(r13)
334 std r12,PACA_EXGEN+EX_R12(r13) 359 std r12,PACA_EXGEN+EX_R12(r13)
335 mfspr r9,SPRN_SPRG_HSCRATCH0 360 mfspr r9,SPRN_SPRG_HSCRATCH0
@@ -372,8 +397,10 @@ machine_check_pSeries:
372machine_check_fwnmi: 397machine_check_fwnmi:
373 HMT_MEDIUM_PPR_DISCARD 398 HMT_MEDIUM_PPR_DISCARD
374 SET_SCRATCH0(r13) /* save r13 */ 399 SET_SCRATCH0(r13) /* save r13 */
375 EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common, 400 EXCEPTION_PROLOG_0(PACA_EXMC)
376 EXC_STD, KVMTEST, 0x200) 401machine_check_pSeries_0:
402 EXCEPTION_PROLOG_1(PACA_EXMC, KVMTEST, 0x200)
403 EXCEPTION_PROLOG_PSERIES_1(machine_check_common, EXC_STD)
377 KVM_HANDLER_SKIP(PACA_EXMC, EXC_STD, 0x200) 404 KVM_HANDLER_SKIP(PACA_EXMC, EXC_STD, 0x200)
378 405
379 /* moved from 0x300 */ 406 /* moved from 0x300 */
@@ -510,24 +537,26 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_206)
510 537
511 .align 7 538 .align 7
512 /* moved from 0xe00 */ 539 /* moved from 0xe00 */
513 STD_EXCEPTION_HV(., 0xe02, h_data_storage) 540 STD_EXCEPTION_HV_OOL(0xe02, h_data_storage)
514 KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0xe02) 541 KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0xe02)
515 STD_EXCEPTION_HV(., 0xe22, h_instr_storage) 542 STD_EXCEPTION_HV_OOL(0xe22, h_instr_storage)
516 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe22) 543 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe22)
517 STD_EXCEPTION_HV(., 0xe42, emulation_assist) 544 STD_EXCEPTION_HV_OOL(0xe42, emulation_assist)
518 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe42) 545 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe42)
519 STD_EXCEPTION_HV(., 0xe62, hmi_exception) /* need to flush cache ? */ 546 STD_EXCEPTION_HV_OOL(0xe62, hmi_exception) /* need to flush cache ? */
520 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe62) 547 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe62)
521 MASKABLE_EXCEPTION_HV(., 0xe82, h_doorbell) 548 MASKABLE_EXCEPTION_HV_OOL(0xe82, h_doorbell)
522 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe82) 549 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe82)
523 550
524 /* moved from 0xf00 */ 551 /* moved from 0xf00 */
525 STD_EXCEPTION_PSERIES(., 0xf00, performance_monitor) 552 STD_EXCEPTION_PSERIES_OOL(0xf00, performance_monitor)
526 KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf00) 553 KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf00)
527 STD_EXCEPTION_PSERIES(., 0xf20, altivec_unavailable) 554 STD_EXCEPTION_PSERIES_OOL(0xf20, altivec_unavailable)
528 KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf20) 555 KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf20)
529 STD_EXCEPTION_PSERIES(., 0xf40, vsx_unavailable) 556 STD_EXCEPTION_PSERIES_OOL(0xf40, vsx_unavailable)
530 KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf40) 557 KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf40)
558 STD_EXCEPTION_PSERIES_OOL(0xf60, tm_unavailable)
559 KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf60)
531 560
532/* 561/*
533 * An interrupt came in while soft-disabled. We set paca->irq_happened, then: 562 * An interrupt came in while soft-disabled. We set paca->irq_happened, then:
@@ -718,8 +747,8 @@ machine_check_common:
718 . = 0x4380 747 . = 0x4380
719 .globl data_access_slb_relon_pSeries 748 .globl data_access_slb_relon_pSeries
720data_access_slb_relon_pSeries: 749data_access_slb_relon_pSeries:
721 HMT_MEDIUM_PPR_DISCARD
722 SET_SCRATCH0(r13) 750 SET_SCRATCH0(r13)
751 EXCEPTION_PROLOG_0(PACA_EXSLB)
723 EXCEPTION_PROLOG_1(PACA_EXSLB, NOTEST, 0x380) 752 EXCEPTION_PROLOG_1(PACA_EXSLB, NOTEST, 0x380)
724 std r3,PACA_EXSLB+EX_R3(r13) 753 std r3,PACA_EXSLB+EX_R3(r13)
725 mfspr r3,SPRN_DAR 754 mfspr r3,SPRN_DAR
@@ -743,8 +772,8 @@ data_access_slb_relon_pSeries:
743 . = 0x4480 772 . = 0x4480
744 .globl instruction_access_slb_relon_pSeries 773 .globl instruction_access_slb_relon_pSeries
745instruction_access_slb_relon_pSeries: 774instruction_access_slb_relon_pSeries:
746 HMT_MEDIUM_PPR_DISCARD
747 SET_SCRATCH0(r13) 775 SET_SCRATCH0(r13)
776 EXCEPTION_PROLOG_0(PACA_EXSLB)
748 EXCEPTION_PROLOG_1(PACA_EXSLB, NOTEST, 0x480) 777 EXCEPTION_PROLOG_1(PACA_EXSLB, NOTEST, 0x480)
749 std r3,PACA_EXSLB+EX_R3(r13) 778 std r3,PACA_EXSLB+EX_R3(r13)
750 mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */ 779 mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */
@@ -788,55 +817,64 @@ system_call_relon_pSeries:
788 STD_RELON_EXCEPTION_PSERIES(0x4d00, 0xd00, single_step) 817 STD_RELON_EXCEPTION_PSERIES(0x4d00, 0xd00, single_step)
789 818
790 . = 0x4e00 819 . = 0x4e00
820 SET_SCRATCH0(r13)
821 EXCEPTION_PROLOG_0(PACA_EXGEN)
791 b h_data_storage_relon_hv 822 b h_data_storage_relon_hv
792 823
793 . = 0x4e20 824 . = 0x4e20
825 SET_SCRATCH0(r13)
826 EXCEPTION_PROLOG_0(PACA_EXGEN)
794 b h_instr_storage_relon_hv 827 b h_instr_storage_relon_hv
795 828
796 . = 0x4e40 829 . = 0x4e40
830 SET_SCRATCH0(r13)
831 EXCEPTION_PROLOG_0(PACA_EXGEN)
797 b emulation_assist_relon_hv 832 b emulation_assist_relon_hv
798 833
799 . = 0x4e50
800 b hmi_exception_relon_hv
801
802 . = 0x4e60 834 . = 0x4e60
835 SET_SCRATCH0(r13)
836 EXCEPTION_PROLOG_0(PACA_EXGEN)
803 b hmi_exception_relon_hv 837 b hmi_exception_relon_hv
804 838
805 . = 0x4e80 839 . = 0x4e80
840 SET_SCRATCH0(r13)
841 EXCEPTION_PROLOG_0(PACA_EXGEN)
806 b h_doorbell_relon_hv 842 b h_doorbell_relon_hv
807 843
808performance_monitor_relon_pSeries_1: 844performance_monitor_relon_pSeries_1:
809 . = 0x4f00 845 . = 0x4f00
846 SET_SCRATCH0(r13)
847 EXCEPTION_PROLOG_0(PACA_EXGEN)
810 b performance_monitor_relon_pSeries 848 b performance_monitor_relon_pSeries
811 849
812altivec_unavailable_relon_pSeries_1: 850altivec_unavailable_relon_pSeries_1:
813 . = 0x4f20 851 . = 0x4f20
852 SET_SCRATCH0(r13)
853 EXCEPTION_PROLOG_0(PACA_EXGEN)
814 b altivec_unavailable_relon_pSeries 854 b altivec_unavailable_relon_pSeries
815 855
816vsx_unavailable_relon_pSeries_1: 856vsx_unavailable_relon_pSeries_1:
817 . = 0x4f40 857 . = 0x4f40
858 SET_SCRATCH0(r13)
859 EXCEPTION_PROLOG_0(PACA_EXGEN)
818 b vsx_unavailable_relon_pSeries 860 b vsx_unavailable_relon_pSeries
819 861
820#ifdef CONFIG_CBE_RAS 862tm_unavailable_relon_pSeries_1:
821 STD_RELON_EXCEPTION_HV(0x5200, 0x1202, cbe_system_error) 863 . = 0x4f60
822#endif /* CONFIG_CBE_RAS */ 864 SET_SCRATCH0(r13)
865 EXCEPTION_PROLOG_0(PACA_EXGEN)
866 b tm_unavailable_relon_pSeries
867
823 STD_RELON_EXCEPTION_PSERIES(0x5300, 0x1300, instruction_breakpoint) 868 STD_RELON_EXCEPTION_PSERIES(0x5300, 0x1300, instruction_breakpoint)
824#ifdef CONFIG_PPC_DENORMALISATION 869#ifdef CONFIG_PPC_DENORMALISATION
825 . = 0x5500 870 . = 0x5500
826 b denorm_exception_hv 871 b denorm_exception_hv
827#endif 872#endif
828#ifdef CONFIG_CBE_RAS
829 STD_RELON_EXCEPTION_HV(0x5600, 0x1602, cbe_maintenance)
830#else
831#ifdef CONFIG_HVC_SCOM 873#ifdef CONFIG_HVC_SCOM
832 STD_RELON_EXCEPTION_HV(0x5600, 0x1600, maintence_interrupt) 874 STD_RELON_EXCEPTION_HV(0x5600, 0x1600, maintence_interrupt)
833 KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1600) 875 KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1600)
834#endif /* CONFIG_HVC_SCOM */ 876#endif /* CONFIG_HVC_SCOM */
835#endif /* CONFIG_CBE_RAS */
836 STD_RELON_EXCEPTION_PSERIES(0x5700, 0x1700, altivec_assist) 877 STD_RELON_EXCEPTION_PSERIES(0x5700, 0x1700, altivec_assist)
837#ifdef CONFIG_CBE_RAS
838 STD_RELON_EXCEPTION_HV(0x5800, 0x1802, cbe_thermal)
839#endif /* CONFIG_CBE_RAS */
840 878
841 /* Other future vectors */ 879 /* Other future vectors */
842 .align 7 880 .align 7
@@ -1138,9 +1176,26 @@ fp_unavailable_common:
1138 addi r3,r1,STACK_FRAME_OVERHEAD 1176 addi r3,r1,STACK_FRAME_OVERHEAD
1139 bl .kernel_fp_unavailable_exception 1177 bl .kernel_fp_unavailable_exception
1140 BUG_OPCODE 1178 BUG_OPCODE
11411: bl .load_up_fpu 11791:
1180#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1181BEGIN_FTR_SECTION
1182 /* Test if 2 TM state bits are zero. If non-zero (ie. userspace was in
1183 * transaction), go do TM stuff
1184 */
1185 rldicl. r0, r12, (64-MSR_TS_LG), (64-2)
1186 bne- 2f
1187END_FTR_SECTION_IFSET(CPU_FTR_TM)
1188#endif
1189 bl .load_up_fpu
1142 b fast_exception_return 1190 b fast_exception_return
1143 1191#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
11922: /* User process was in a transaction */
1193 bl .save_nvgprs
1194 DISABLE_INTS
1195 addi r3,r1,STACK_FRAME_OVERHEAD
1196 bl .fp_unavailable_tm
1197 b .ret_from_except
1198#endif
1144 .align 7 1199 .align 7
1145 .globl altivec_unavailable_common 1200 .globl altivec_unavailable_common
1146altivec_unavailable_common: 1201altivec_unavailable_common:
@@ -1148,8 +1203,25 @@ altivec_unavailable_common:
1148#ifdef CONFIG_ALTIVEC 1203#ifdef CONFIG_ALTIVEC
1149BEGIN_FTR_SECTION 1204BEGIN_FTR_SECTION
1150 beq 1f 1205 beq 1f
1206#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1207 BEGIN_FTR_SECTION_NESTED(69)
1208 /* Test if 2 TM state bits are zero. If non-zero (ie. userspace was in
1209 * transaction), go do TM stuff
1210 */
1211 rldicl. r0, r12, (64-MSR_TS_LG), (64-2)
1212 bne- 2f
1213 END_FTR_SECTION_NESTED(CPU_FTR_TM, CPU_FTR_TM, 69)
1214#endif
1151 bl .load_up_altivec 1215 bl .load_up_altivec
1152 b fast_exception_return 1216 b fast_exception_return
1217#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
12182: /* User process was in a transaction */
1219 bl .save_nvgprs
1220 DISABLE_INTS
1221 addi r3,r1,STACK_FRAME_OVERHEAD
1222 bl .altivec_unavailable_tm
1223 b .ret_from_except
1224#endif
11531: 12251:
1154END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) 1226END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
1155#endif 1227#endif
@@ -1166,7 +1238,24 @@ vsx_unavailable_common:
1166#ifdef CONFIG_VSX 1238#ifdef CONFIG_VSX
1167BEGIN_FTR_SECTION 1239BEGIN_FTR_SECTION
1168 beq 1f 1240 beq 1f
1241#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1242 BEGIN_FTR_SECTION_NESTED(69)
1243 /* Test if 2 TM state bits are zero. If non-zero (ie. userspace was in
1244 * transaction), go do TM stuff
1245 */
1246 rldicl. r0, r12, (64-MSR_TS_LG), (64-2)
1247 bne- 2f
1248 END_FTR_SECTION_NESTED(CPU_FTR_TM, CPU_FTR_TM, 69)
1249#endif
1169 b .load_up_vsx 1250 b .load_up_vsx
1251#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
12522: /* User process was in a transaction */
1253 bl .save_nvgprs
1254 DISABLE_INTS
1255 addi r3,r1,STACK_FRAME_OVERHEAD
1256 bl .vsx_unavailable_tm
1257 b .ret_from_except
1258#endif
11701: 12591:
1171END_FTR_SECTION_IFSET(CPU_FTR_VSX) 1260END_FTR_SECTION_IFSET(CPU_FTR_VSX)
1172#endif 1261#endif
@@ -1177,24 +1266,35 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
1177 b .ret_from_except 1266 b .ret_from_except
1178 1267
1179 .align 7 1268 .align 7
1269 .globl tm_unavailable_common
1270tm_unavailable_common:
1271 EXCEPTION_PROLOG_COMMON(0xf60, PACA_EXGEN)
1272 bl .save_nvgprs
1273 DISABLE_INTS
1274 addi r3,r1,STACK_FRAME_OVERHEAD
1275 bl .tm_unavailable_exception
1276 b .ret_from_except
1277
1278 .align 7
1180 .globl __end_handlers 1279 .globl __end_handlers
1181__end_handlers: 1280__end_handlers:
1182 1281
1183 /* Equivalents to the above handlers for relocation-on interrupt vectors */ 1282 /* Equivalents to the above handlers for relocation-on interrupt vectors */
1184 STD_RELON_EXCEPTION_HV(., 0xe00, h_data_storage) 1283 STD_RELON_EXCEPTION_HV_OOL(0xe00, h_data_storage)
1185 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe00) 1284 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe00)
1186 STD_RELON_EXCEPTION_HV(., 0xe20, h_instr_storage) 1285 STD_RELON_EXCEPTION_HV_OOL(0xe20, h_instr_storage)
1187 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe20) 1286 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe20)
1188 STD_RELON_EXCEPTION_HV(., 0xe40, emulation_assist) 1287 STD_RELON_EXCEPTION_HV_OOL(0xe40, emulation_assist)
1189 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe40) 1288 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe40)
1190 STD_RELON_EXCEPTION_HV(., 0xe60, hmi_exception) 1289 STD_RELON_EXCEPTION_HV_OOL(0xe60, hmi_exception)
1191 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe60) 1290 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe60)
1192 MASKABLE_RELON_EXCEPTION_HV(., 0xe80, h_doorbell) 1291 MASKABLE_RELON_EXCEPTION_HV_OOL(0xe80, h_doorbell)
1193 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe80) 1292 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe80)
1194 1293
1195 STD_RELON_EXCEPTION_PSERIES(., 0xf00, performance_monitor) 1294 STD_RELON_EXCEPTION_PSERIES_OOL(0xf00, performance_monitor)
1196 STD_RELON_EXCEPTION_PSERIES(., 0xf20, altivec_unavailable) 1295 STD_RELON_EXCEPTION_PSERIES_OOL(0xf20, altivec_unavailable)
1197 STD_RELON_EXCEPTION_PSERIES(., 0xf40, vsx_unavailable) 1296 STD_RELON_EXCEPTION_PSERIES_OOL(0xf40, vsx_unavailable)
1297 STD_RELON_EXCEPTION_PSERIES_OOL(0xf60, tm_unavailable)
1198 1298
1199#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) 1299#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
1200/* 1300/*
diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S
index e0ada05f2df3..caeaabf11a2f 100644
--- a/arch/powerpc/kernel/fpu.S
+++ b/arch/powerpc/kernel/fpu.S
@@ -35,6 +35,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX); \
352: REST_32VSRS(n,c,base); \ 352: REST_32VSRS(n,c,base); \
363: 363:
37 37
38#define __REST_32FPVSRS_TRANSACT(n,c,base) \
39BEGIN_FTR_SECTION \
40 b 2f; \
41END_FTR_SECTION_IFSET(CPU_FTR_VSX); \
42 REST_32FPRS_TRANSACT(n,base); \
43 b 3f; \
442: REST_32VSRS_TRANSACT(n,c,base); \
453:
46
38#define __SAVE_32FPVSRS(n,c,base) \ 47#define __SAVE_32FPVSRS(n,c,base) \
39BEGIN_FTR_SECTION \ 48BEGIN_FTR_SECTION \
40 b 2f; \ 49 b 2f; \
@@ -45,11 +54,68 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX); \
453: 543:
46#else 55#else
47#define __REST_32FPVSRS(n,b,base) REST_32FPRS(n, base) 56#define __REST_32FPVSRS(n,b,base) REST_32FPRS(n, base)
57#define __REST_32FPVSRS_TRANSACT(n,b,base) REST_32FPRS(n, base)
48#define __SAVE_32FPVSRS(n,b,base) SAVE_32FPRS(n, base) 58#define __SAVE_32FPVSRS(n,b,base) SAVE_32FPRS(n, base)
49#endif 59#endif
50#define REST_32FPVSRS(n,c,base) __REST_32FPVSRS(n,__REG_##c,__REG_##base) 60#define REST_32FPVSRS(n,c,base) __REST_32FPVSRS(n,__REG_##c,__REG_##base)
61#define REST_32FPVSRS_TRANSACT(n,c,base) \
62 __REST_32FPVSRS_TRANSACT(n,__REG_##c,__REG_##base)
51#define SAVE_32FPVSRS(n,c,base) __SAVE_32FPVSRS(n,__REG_##c,__REG_##base) 63#define SAVE_32FPVSRS(n,c,base) __SAVE_32FPVSRS(n,__REG_##c,__REG_##base)
52 64
65#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
66/*
67 * Wrapper to call load_up_fpu from C.
68 * void do_load_up_fpu(struct pt_regs *regs);
69 */
70_GLOBAL(do_load_up_fpu)
71 mflr r0
72 std r0, 16(r1)
73 stdu r1, -112(r1)
74
75 subi r6, r3, STACK_FRAME_OVERHEAD
76 /* load_up_fpu expects r12=MSR, r13=PACA, and returns
77 * with r12 = new MSR.
78 */
79 ld r12,_MSR(r6)
80 GET_PACA(r13)
81
82 bl load_up_fpu
83 std r12,_MSR(r6)
84
85 ld r0, 112+16(r1)
86 addi r1, r1, 112
87 mtlr r0
88 blr
89
90
91/* void do_load_up_transact_fpu(struct thread_struct *thread)
92 *
93 * This is similar to load_up_fpu but for the transactional version of the FP
94 * register set. It doesn't mess with the task MSR or valid flags.
95 * Furthermore, we don't do lazy FP with TM currently.
96 */
97_GLOBAL(do_load_up_transact_fpu)
98 mfmsr r6
99 ori r5,r6,MSR_FP
100#ifdef CONFIG_VSX
101BEGIN_FTR_SECTION
102 oris r5,r5,MSR_VSX@h
103END_FTR_SECTION_IFSET(CPU_FTR_VSX)
104#endif
105 SYNC
106 MTMSRD(r5)
107
108 lfd fr0,THREAD_TRANSACT_FPSCR(r3)
109 MTFSF_L(fr0)
110 REST_32FPVSRS_TRANSACT(0, R4, R3)
111
112 /* FP/VSX off again */
113 MTMSRD(r6)
114 SYNC
115
116 blr
117#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
118
53/* 119/*
54 * This task wants to use the FPU now. 120 * This task wants to use the FPU now.
55 * On UP, disable FP for the task which had the FPU previously, 121 * On UP, disable FP for the task which had the FPU previously,
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index cd6da855090c..f8f24685f10a 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -120,8 +120,6 @@ struct slb_shadow slb_shadow[] __cacheline_aligned = {
120struct paca_struct *paca; 120struct paca_struct *paca;
121EXPORT_SYMBOL(paca); 121EXPORT_SYMBOL(paca);
122 122
123struct paca_struct boot_paca;
124
125void __init initialise_paca(struct paca_struct *new_paca, int cpu) 123void __init initialise_paca(struct paca_struct *new_paca, int cpu)
126{ 124{
127 /* The TOC register (GPR2) points 32kB into the TOC, so that 64kB 125 /* The TOC register (GPR2) points 32kB into the TOC, so that 64kB
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 96e31de89b43..59dd545fdde1 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -50,6 +50,7 @@
50#include <asm/runlatch.h> 50#include <asm/runlatch.h>
51#include <asm/syscalls.h> 51#include <asm/syscalls.h>
52#include <asm/switch_to.h> 52#include <asm/switch_to.h>
53#include <asm/tm.h>
53#include <asm/debug.h> 54#include <asm/debug.h>
54#ifdef CONFIG_PPC64 55#ifdef CONFIG_PPC64
55#include <asm/firmware.h> 56#include <asm/firmware.h>
@@ -57,6 +58,13 @@
57#include <linux/kprobes.h> 58#include <linux/kprobes.h>
58#include <linux/kdebug.h> 59#include <linux/kdebug.h>
59 60
61/* Transactional Memory debug */
62#ifdef TM_DEBUG_SW
63#define TM_DEBUG(x...) printk(KERN_INFO x)
64#else
65#define TM_DEBUG(x...) do { } while(0)
66#endif
67
60extern unsigned long _get_SP(void); 68extern unsigned long _get_SP(void);
61 69
62#ifndef CONFIG_SMP 70#ifndef CONFIG_SMP
@@ -460,6 +468,117 @@ static inline bool hw_brk_match(struct arch_hw_breakpoint *a,
460 return false; 468 return false;
461 return true; 469 return true;
462} 470}
471#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
472static inline void tm_reclaim_task(struct task_struct *tsk)
473{
474 /* We have to work out if we're switching from/to a task that's in the
475 * middle of a transaction.
476 *
477 * In switching we need to maintain a 2nd register state as
478 * oldtask->thread.ckpt_regs. We tm_reclaim(oldproc); this saves the
479 * checkpointed (tbegin) state in ckpt_regs and saves the transactional
480 * (current) FPRs into oldtask->thread.transact_fpr[].
481 *
482 * We also context switch (save) TFHAR/TEXASR/TFIAR in here.
483 */
484 struct thread_struct *thr = &tsk->thread;
485
486 if (!thr->regs)
487 return;
488
489 if (!MSR_TM_ACTIVE(thr->regs->msr))
490 goto out_and_saveregs;
491
492 /* Stash the original thread MSR, as giveup_fpu et al will
493 * modify it. We hold onto it to see whether the task used
494 * FP & vector regs.
495 */
496 thr->tm_orig_msr = thr->regs->msr;
497
498 TM_DEBUG("--- tm_reclaim on pid %d (NIP=%lx, "
499 "ccr=%lx, msr=%lx, trap=%lx)\n",
500 tsk->pid, thr->regs->nip,
501 thr->regs->ccr, thr->regs->msr,
502 thr->regs->trap);
503
504 tm_reclaim(thr, thr->regs->msr, TM_CAUSE_RESCHED);
505
506 TM_DEBUG("--- tm_reclaim on pid %d complete\n",
507 tsk->pid);
508
509out_and_saveregs:
510 /* Always save the regs here, even if a transaction's not active.
511 * This context-switches a thread's TM info SPRs. We do it here to
512 * be consistent with the restore path (in recheckpoint) which
513 * cannot happen later in _switch().
514 */
515 tm_save_sprs(thr);
516}
517
518static inline void tm_recheckpoint_new_task(struct task_struct *new)
519{
520 unsigned long msr;
521
522 if (!cpu_has_feature(CPU_FTR_TM))
523 return;
524
525 /* Recheckpoint the registers of the thread we're about to switch to.
526 *
527 * If the task was using FP, we non-lazily reload both the original and
528 * the speculative FP register states. This is because the kernel
529 * doesn't see if/when a TM rollback occurs, so if we take an FP
530 * unavoidable later, we are unable to determine which set of FP regs
531 * need to be restored.
532 */
533 if (!new->thread.regs)
534 return;
535
536 /* The TM SPRs are restored here, so that TEXASR.FS can be set
537 * before the trecheckpoint and no explosion occurs.
538 */
539 tm_restore_sprs(&new->thread);
540
541 if (!MSR_TM_ACTIVE(new->thread.regs->msr))
542 return;
543 msr = new->thread.tm_orig_msr;
544 /* Recheckpoint to restore original checkpointed register state. */
545 TM_DEBUG("*** tm_recheckpoint of pid %d "
546 "(new->msr 0x%lx, new->origmsr 0x%lx)\n",
547 new->pid, new->thread.regs->msr, msr);
548
549 /* This loads the checkpointed FP/VEC state, if used */
550 tm_recheckpoint(&new->thread, msr);
551
552 /* This loads the speculative FP/VEC state, if used */
553 if (msr & MSR_FP) {
554 do_load_up_transact_fpu(&new->thread);
555 new->thread.regs->msr |=
556 (MSR_FP | new->thread.fpexc_mode);
557 }
558 if (msr & MSR_VEC) {
559 do_load_up_transact_altivec(&new->thread);
560 new->thread.regs->msr |= MSR_VEC;
561 }
562 /* We may as well turn on VSX too since all the state is restored now */
563 if (msr & MSR_VSX)
564 new->thread.regs->msr |= MSR_VSX;
565
566 TM_DEBUG("*** tm_recheckpoint of pid %d complete "
567 "(kernel msr 0x%lx)\n",
568 new->pid, mfmsr());
569}
570
571static inline void __switch_to_tm(struct task_struct *prev)
572{
573 if (cpu_has_feature(CPU_FTR_TM)) {
574 tm_enable();
575 tm_reclaim_task(prev);
576 }
577}
578#else
579#define tm_recheckpoint_new_task(new)
580#define __switch_to_tm(prev)
581#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
463 582
464struct task_struct *__switch_to(struct task_struct *prev, 583struct task_struct *__switch_to(struct task_struct *prev,
465 struct task_struct *new) 584 struct task_struct *new)
@@ -471,6 +590,8 @@ struct task_struct *__switch_to(struct task_struct *prev,
471 struct ppc64_tlb_batch *batch; 590 struct ppc64_tlb_batch *batch;
472#endif 591#endif
473 592
593 __switch_to_tm(prev);
594
474#ifdef CONFIG_SMP 595#ifdef CONFIG_SMP
475 /* avoid complexity of lazy save/restore of fpu 596 /* avoid complexity of lazy save/restore of fpu
476 * by just saving it every time we switch out if 597 * by just saving it every time we switch out if
@@ -586,6 +707,9 @@ struct task_struct *__switch_to(struct task_struct *prev,
586 * of sync. Hard disable here. 707 * of sync. Hard disable here.
587 */ 708 */
588 hard_irq_disable(); 709 hard_irq_disable();
710
711 tm_recheckpoint_new_task(new);
712
589 last = _switch(old_thread, new_thread); 713 last = _switch(old_thread, new_thread);
590 714
591#ifdef CONFIG_PPC_BOOK3S_64 715#ifdef CONFIG_PPC_BOOK3S_64
@@ -747,6 +871,9 @@ void show_regs(struct pt_regs * regs)
747 printk("NIP ["REG"] %pS\n", regs->nip, (void *)regs->nip); 871 printk("NIP ["REG"] %pS\n", regs->nip, (void *)regs->nip);
748 printk("LR ["REG"] %pS\n", regs->link, (void *)regs->link); 872 printk("LR ["REG"] %pS\n", regs->link, (void *)regs->link);
749#endif 873#endif
874#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
875 printk("PACATMSCRATCH [%llx]\n", get_paca()->tm_scratch);
876#endif
750 show_stack(current, (unsigned long *) regs->gpr[1]); 877 show_stack(current, (unsigned long *) regs->gpr[1]);
751 if (!user_mode(regs)) 878 if (!user_mode(regs))
752 show_instructions(regs); 879 show_instructions(regs);
@@ -958,7 +1085,6 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
958 regs->msr = MSR_USER32; 1085 regs->msr = MSR_USER32;
959 } 1086 }
960#endif 1087#endif
961
962 discard_lazy_cpu_state(); 1088 discard_lazy_cpu_state();
963#ifdef CONFIG_VSX 1089#ifdef CONFIG_VSX
964 current->thread.used_vsr = 0; 1090 current->thread.used_vsr = 0;
@@ -978,6 +1104,13 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
978 current->thread.spefscr = 0; 1104 current->thread.spefscr = 0;
979 current->thread.used_spe = 0; 1105 current->thread.used_spe = 0;
980#endif /* CONFIG_SPE */ 1106#endif /* CONFIG_SPE */
1107#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1108 if (cpu_has_feature(CPU_FTR_TM))
1109 regs->msr |= MSR_TM;
1110 current->thread.tm_tfhar = 0;
1111 current->thread.tm_texasr = 0;
1112 current->thread.tm_tfiar = 0;
1113#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
981} 1114}
982 1115
983#define PR_FP_ALL_EXCEPT (PR_FP_EXC_DIV | PR_FP_EXC_OVF | PR_FP_EXC_UND \ 1116#define PR_FP_ALL_EXCEPT (PR_FP_EXC_DIV | PR_FP_EXC_OVF | PR_FP_EXC_UND \
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 6da881b35dac..75fbaceb5c87 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -156,6 +156,15 @@ early_param("smt-enabled", early_smt_enabled);
156#define check_smt_enabled() 156#define check_smt_enabled()
157#endif /* CONFIG_SMP */ 157#endif /* CONFIG_SMP */
158 158
159/** Fix up paca fields required for the boot cpu */
160static void fixup_boot_paca(void)
161{
162 /* The boot cpu is started */
163 get_paca()->cpu_start = 1;
164 /* Allow percpu accesses to work until we setup percpu data */
165 get_paca()->data_offset = 0;
166}
167
159/* 168/*
160 * Early initialization entry point. This is called by head.S 169 * Early initialization entry point. This is called by head.S
161 * with MMU translation disabled. We rely on the "feature" of 170 * with MMU translation disabled. We rely on the "feature" of
@@ -177,6 +186,8 @@ early_param("smt-enabled", early_smt_enabled);
177 186
178void __init early_setup(unsigned long dt_ptr) 187void __init early_setup(unsigned long dt_ptr)
179{ 188{
189 static __initdata struct paca_struct boot_paca;
190
180 /* -------- printk is _NOT_ safe to use here ! ------- */ 191 /* -------- printk is _NOT_ safe to use here ! ------- */
181 192
182 /* Identify CPU type */ 193 /* Identify CPU type */
@@ -185,6 +196,7 @@ void __init early_setup(unsigned long dt_ptr)
185 /* Assume we're on cpu 0 for now. Don't write to the paca yet! */ 196 /* Assume we're on cpu 0 for now. Don't write to the paca yet! */
186 initialise_paca(&boot_paca, 0); 197 initialise_paca(&boot_paca, 0);
187 setup_paca(&boot_paca); 198 setup_paca(&boot_paca);
199 fixup_boot_paca();
188 200
189 /* Initialize lockdep early or else spinlocks will blow */ 201 /* Initialize lockdep early or else spinlocks will blow */
190 lockdep_init(); 202 lockdep_init();
@@ -205,11 +217,7 @@ void __init early_setup(unsigned long dt_ptr)
205 217
206 /* Now we know the logical id of our boot cpu, setup the paca. */ 218 /* Now we know the logical id of our boot cpu, setup the paca. */
207 setup_paca(&paca[boot_cpuid]); 219 setup_paca(&paca[boot_cpuid]);
208 220 fixup_boot_paca();
209 /* Fix up paca fields required for the boot cpu */
210 get_paca()->cpu_start = 1;
211 /* Allow percpu accesses to "work" until we setup percpu data */
212 get_paca()->data_offset = 0;
213 221
214 /* Probe the machine type */ 222 /* Probe the machine type */
215 probe_machine(); 223 probe_machine();
diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h
index e00acb413934..ec84c901ceab 100644
--- a/arch/powerpc/kernel/signal.h
+++ b/arch/powerpc/kernel/signal.h
@@ -25,13 +25,21 @@ extern int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
25 25
26extern unsigned long copy_fpr_to_user(void __user *to, 26extern unsigned long copy_fpr_to_user(void __user *to,
27 struct task_struct *task); 27 struct task_struct *task);
28extern unsigned long copy_transact_fpr_to_user(void __user *to,
29 struct task_struct *task);
28extern unsigned long copy_fpr_from_user(struct task_struct *task, 30extern unsigned long copy_fpr_from_user(struct task_struct *task,
29 void __user *from); 31 void __user *from);
32extern unsigned long copy_transact_fpr_from_user(struct task_struct *task,
33 void __user *from);
30#ifdef CONFIG_VSX 34#ifdef CONFIG_VSX
31extern unsigned long copy_vsx_to_user(void __user *to, 35extern unsigned long copy_vsx_to_user(void __user *to,
32 struct task_struct *task); 36 struct task_struct *task);
37extern unsigned long copy_transact_vsx_to_user(void __user *to,
38 struct task_struct *task);
33extern unsigned long copy_vsx_from_user(struct task_struct *task, 39extern unsigned long copy_vsx_from_user(struct task_struct *task,
34 void __user *from); 40 void __user *from);
41extern unsigned long copy_transact_vsx_from_user(struct task_struct *task,
42 void __user *from);
35#endif 43#endif
36 44
37#ifdef CONFIG_PPC64 45#ifdef CONFIG_PPC64
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 804e323c139d..e4a88d340de6 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -43,6 +43,7 @@
43#include <asm/sigcontext.h> 43#include <asm/sigcontext.h>
44#include <asm/vdso.h> 44#include <asm/vdso.h>
45#include <asm/switch_to.h> 45#include <asm/switch_to.h>
46#include <asm/tm.h>
46#ifdef CONFIG_PPC64 47#ifdef CONFIG_PPC64
47#include "ppc32.h" 48#include "ppc32.h"
48#include <asm/unistd.h> 49#include <asm/unistd.h>
@@ -293,6 +294,10 @@ long sys_sigaction(int sig, struct old_sigaction __user *act,
293struct sigframe { 294struct sigframe {
294 struct sigcontext sctx; /* the sigcontext */ 295 struct sigcontext sctx; /* the sigcontext */
295 struct mcontext mctx; /* all the register values */ 296 struct mcontext mctx; /* all the register values */
297#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
298 struct sigcontext sctx_transact;
299 struct mcontext mctx_transact;
300#endif
296 /* 301 /*
297 * Programs using the rs6000/xcoff abi can save up to 19 gp 302 * Programs using the rs6000/xcoff abi can save up to 19 gp
298 * regs and 18 fp regs below sp before decrementing it. 303 * regs and 18 fp regs below sp before decrementing it.
@@ -321,6 +326,9 @@ struct rt_sigframe {
321 struct siginfo info; 326 struct siginfo info;
322#endif 327#endif
323 struct ucontext uc; 328 struct ucontext uc;
329#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
330 struct ucontext uc_transact;
331#endif
324 /* 332 /*
325 * Programs using the rs6000/xcoff abi can save up to 19 gp 333 * Programs using the rs6000/xcoff abi can save up to 19 gp
326 * regs and 18 fp regs below sp before decrementing it. 334 * regs and 18 fp regs below sp before decrementing it.
@@ -381,6 +389,61 @@ unsigned long copy_vsx_from_user(struct task_struct *task,
381 task->thread.fpr[i][TS_VSRLOWOFFSET] = buf[i]; 389 task->thread.fpr[i][TS_VSRLOWOFFSET] = buf[i];
382 return 0; 390 return 0;
383} 391}
392
393#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
394unsigned long copy_transact_fpr_to_user(void __user *to,
395 struct task_struct *task)
396{
397 double buf[ELF_NFPREG];
398 int i;
399
400 /* save FPR copy to local buffer then write to the thread_struct */
401 for (i = 0; i < (ELF_NFPREG - 1) ; i++)
402 buf[i] = task->thread.TS_TRANS_FPR(i);
403 memcpy(&buf[i], &task->thread.transact_fpscr, sizeof(double));
404 return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
405}
406
407unsigned long copy_transact_fpr_from_user(struct task_struct *task,
408 void __user *from)
409{
410 double buf[ELF_NFPREG];
411 int i;
412
413 if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
414 return 1;
415 for (i = 0; i < (ELF_NFPREG - 1) ; i++)
416 task->thread.TS_TRANS_FPR(i) = buf[i];
417 memcpy(&task->thread.transact_fpscr, &buf[i], sizeof(double));
418
419 return 0;
420}
421
422unsigned long copy_transact_vsx_to_user(void __user *to,
423 struct task_struct *task)
424{
425 double buf[ELF_NVSRHALFREG];
426 int i;
427
428 /* save FPR copy to local buffer then write to the thread_struct */
429 for (i = 0; i < ELF_NVSRHALFREG; i++)
430 buf[i] = task->thread.transact_fpr[i][TS_VSRLOWOFFSET];
431 return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
432}
433
434unsigned long copy_transact_vsx_from_user(struct task_struct *task,
435 void __user *from)
436{
437 double buf[ELF_NVSRHALFREG];
438 int i;
439
440 if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
441 return 1;
442 for (i = 0; i < ELF_NVSRHALFREG ; i++)
443 task->thread.transact_fpr[i][TS_VSRLOWOFFSET] = buf[i];
444 return 0;
445}
446#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
384#else 447#else
385inline unsigned long copy_fpr_to_user(void __user *to, 448inline unsigned long copy_fpr_to_user(void __user *to,
386 struct task_struct *task) 449 struct task_struct *task)
@@ -395,6 +458,22 @@ inline unsigned long copy_fpr_from_user(struct task_struct *task,
395 return __copy_from_user(task->thread.fpr, from, 458 return __copy_from_user(task->thread.fpr, from,
396 ELF_NFPREG * sizeof(double)); 459 ELF_NFPREG * sizeof(double));
397} 460}
461
462#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
463inline unsigned long copy_transact_fpr_to_user(void __user *to,
464 struct task_struct *task)
465{
466 return __copy_to_user(to, task->thread.transact_fpr,
467 ELF_NFPREG * sizeof(double));
468}
469
470inline unsigned long copy_transact_fpr_from_user(struct task_struct *task,
471 void __user *from)
472{
473 return __copy_from_user(task->thread.transact_fpr, from,
474 ELF_NFPREG * sizeof(double));
475}
476#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
398#endif 477#endif
399 478
400/* 479/*
@@ -483,6 +562,156 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
483 return 0; 562 return 0;
484} 563}
485 564
565#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
566/*
567 * Save the current user registers on the user stack.
568 * We only save the altivec/spe registers if the process has used
569 * altivec/spe instructions at some point.
570 * We also save the transactional registers to a second ucontext in the
571 * frame.
572 *
573 * See save_user_regs() and signal_64.c:setup_tm_sigcontexts().
574 */
575static int save_tm_user_regs(struct pt_regs *regs,
576 struct mcontext __user *frame,
577 struct mcontext __user *tm_frame, int sigret)
578{
579 unsigned long msr = regs->msr;
580
581 /* tm_reclaim rolls back all reg states, updating thread.ckpt_regs,
582 * thread.transact_fpr[], thread.transact_vr[], etc.
583 */
584 tm_enable();
585 tm_reclaim(&current->thread, msr, TM_CAUSE_SIGNAL);
586
587 /* Make sure floating point registers are stored in regs */
588 flush_fp_to_thread(current);
589
590 /* Save both sets of general registers */
591 if (save_general_regs(&current->thread.ckpt_regs, frame)
592 || save_general_regs(regs, tm_frame))
593 return 1;
594
595 /* Stash the top half of the 64bit MSR into the 32bit MSR word
596 * of the transactional mcontext. This way we have a backward-compatible
597 * MSR in the 'normal' (checkpointed) mcontext and additionally one can
598 * also look at what type of transaction (T or S) was active at the
599 * time of the signal.
600 */
601 if (__put_user((msr >> 32), &tm_frame->mc_gregs[PT_MSR]))
602 return 1;
603
604#ifdef CONFIG_ALTIVEC
605 /* save altivec registers */
606 if (current->thread.used_vr) {
607 flush_altivec_to_thread(current);
608 if (__copy_to_user(&frame->mc_vregs, current->thread.vr,
609 ELF_NVRREG * sizeof(vector128)))
610 return 1;
611 if (msr & MSR_VEC) {
612 if (__copy_to_user(&tm_frame->mc_vregs,
613 current->thread.transact_vr,
614 ELF_NVRREG * sizeof(vector128)))
615 return 1;
616 } else {
617 if (__copy_to_user(&tm_frame->mc_vregs,
618 current->thread.vr,
619 ELF_NVRREG * sizeof(vector128)))
620 return 1;
621 }
622
623 /* set MSR_VEC in the saved MSR value to indicate that
624 * frame->mc_vregs contains valid data
625 */
626 msr |= MSR_VEC;
627 }
628
629 /* We always copy to/from vrsave, it's 0 if we don't have or don't
630 * use altivec. Since VSCR only contains 32 bits saved in the least
631 * significant bits of a vector, we "cheat" and stuff VRSAVE in the
632 * most significant bits of that same vector. --BenH
633 */
634 if (__put_user(current->thread.vrsave,
635 (u32 __user *)&frame->mc_vregs[32]))
636 return 1;
637 if (msr & MSR_VEC) {
638 if (__put_user(current->thread.transact_vrsave,
639 (u32 __user *)&tm_frame->mc_vregs[32]))
640 return 1;
641 } else {
642 if (__put_user(current->thread.vrsave,
643 (u32 __user *)&tm_frame->mc_vregs[32]))
644 return 1;
645 }
646#endif /* CONFIG_ALTIVEC */
647
648 if (copy_fpr_to_user(&frame->mc_fregs, current))
649 return 1;
650 if (msr & MSR_FP) {
651 if (copy_transact_fpr_to_user(&tm_frame->mc_fregs, current))
652 return 1;
653 } else {
654 if (copy_fpr_to_user(&tm_frame->mc_fregs, current))
655 return 1;
656 }
657
658#ifdef CONFIG_VSX
659 /*
660 * Copy VSR 0-31 upper half from thread_struct to local
661 * buffer, then write that to userspace. Also set MSR_VSX in
662 * the saved MSR value to indicate that frame->mc_vregs
663 * contains valid data
664 */
665 if (current->thread.used_vsr) {
666 __giveup_vsx(current);
667 if (copy_vsx_to_user(&frame->mc_vsregs, current))
668 return 1;
669 if (msr & MSR_VSX) {
670 if (copy_transact_vsx_to_user(&tm_frame->mc_vsregs,
671 current))
672 return 1;
673 } else {
674 if (copy_vsx_to_user(&tm_frame->mc_vsregs, current))
675 return 1;
676 }
677
678 msr |= MSR_VSX;
679 }
680#endif /* CONFIG_VSX */
681#ifdef CONFIG_SPE
682 /* SPE regs are not checkpointed with TM, so this section is
683 * simply the same as in save_user_regs().
684 */
685 if (current->thread.used_spe) {
686 flush_spe_to_thread(current);
687 if (__copy_to_user(&frame->mc_vregs, current->thread.evr,
688 ELF_NEVRREG * sizeof(u32)))
689 return 1;
690 /* set MSR_SPE in the saved MSR value to indicate that
691 * frame->mc_vregs contains valid data */
692 msr |= MSR_SPE;
693 }
694
695 /* We always copy to/from spefscr */
696 if (__put_user(current->thread.spefscr, (u32 __user *)&frame->mc_vregs + ELF_NEVRREG))
697 return 1;
698#endif /* CONFIG_SPE */
699
700 if (__put_user(msr, &frame->mc_gregs[PT_MSR]))
701 return 1;
702 if (sigret) {
703 /* Set up the sigreturn trampoline: li r0,sigret; sc */
704 if (__put_user(0x38000000UL + sigret, &frame->tramp[0])
705 || __put_user(0x44000002UL, &frame->tramp[1]))
706 return 1;
707 flush_icache_range((unsigned long) &frame->tramp[0],
708 (unsigned long) &frame->tramp[2]);
709 }
710
711 return 0;
712}
713#endif
714
486/* 715/*
487 * Restore the current user register values from the user stack, 716 * Restore the current user register values from the user stack,
488 * (except for MSR). 717 * (except for MSR).
@@ -588,6 +817,139 @@ static long restore_user_regs(struct pt_regs *regs,
588 return 0; 817 return 0;
589} 818}
590 819
820#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
821/*
822 * Restore the current user register values from the user stack, except for
823 * MSR, and recheckpoint the original checkpointed register state for processes
824 * in transactions.
825 */
826static long restore_tm_user_regs(struct pt_regs *regs,
827 struct mcontext __user *sr,
828 struct mcontext __user *tm_sr)
829{
830 long err;
831 unsigned long msr;
832#ifdef CONFIG_VSX
833 int i;
834#endif
835
836 /*
837 * restore general registers but not including MSR or SOFTE. Also
838 * take care of keeping r2 (TLS) intact if not a signal.
839 * See comment in signal_64.c:restore_tm_sigcontexts();
840 * TFHAR is restored from the checkpointed NIP; TEXASR and TFIAR
841 * were set by the signal delivery.
842 */
843 err = restore_general_regs(regs, tm_sr);
844 err |= restore_general_regs(&current->thread.ckpt_regs, sr);
845
846 err |= __get_user(current->thread.tm_tfhar, &sr->mc_gregs[PT_NIP]);
847
848 err |= __get_user(msr, &sr->mc_gregs[PT_MSR]);
849 if (err)
850 return 1;
851
852 /* Restore the previous little-endian mode */
853 regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE);
854
855 /*
856 * Do this before updating the thread state in
857 * current->thread.fpr/vr/evr. That way, if we get preempted
858 * and another task grabs the FPU/Altivec/SPE, it won't be
859 * tempted to save the current CPU state into the thread_struct
860 * and corrupt what we are writing there.
861 */
862 discard_lazy_cpu_state();
863
864#ifdef CONFIG_ALTIVEC
865 regs->msr &= ~MSR_VEC;
866 if (msr & MSR_VEC) {
867 /* restore altivec registers from the stack */
868 if (__copy_from_user(current->thread.vr, &sr->mc_vregs,
869 sizeof(sr->mc_vregs)) ||
870 __copy_from_user(current->thread.transact_vr,
871 &tm_sr->mc_vregs,
872 sizeof(sr->mc_vregs)))
873 return 1;
874 } else if (current->thread.used_vr) {
875 memset(current->thread.vr, 0, ELF_NVRREG * sizeof(vector128));
876 memset(current->thread.transact_vr, 0,
877 ELF_NVRREG * sizeof(vector128));
878 }
879
880 /* Always get VRSAVE back */
881 if (__get_user(current->thread.vrsave,
882 (u32 __user *)&sr->mc_vregs[32]) ||
883 __get_user(current->thread.transact_vrsave,
884 (u32 __user *)&tm_sr->mc_vregs[32]))
885 return 1;
886#endif /* CONFIG_ALTIVEC */
887
888 regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
889
890 if (copy_fpr_from_user(current, &sr->mc_fregs) ||
891 copy_transact_fpr_from_user(current, &tm_sr->mc_fregs))
892 return 1;
893
894#ifdef CONFIG_VSX
895 regs->msr &= ~MSR_VSX;
896 if (msr & MSR_VSX) {
897 /*
898 * Restore altivec registers from the stack to a local
899 * buffer, then write this out to the thread_struct
900 */
901 if (copy_vsx_from_user(current, &sr->mc_vsregs) ||
902 copy_transact_vsx_from_user(current, &tm_sr->mc_vsregs))
903 return 1;
904 } else if (current->thread.used_vsr)
905 for (i = 0; i < 32 ; i++) {
906 current->thread.fpr[i][TS_VSRLOWOFFSET] = 0;
907 current->thread.transact_fpr[i][TS_VSRLOWOFFSET] = 0;
908 }
909#endif /* CONFIG_VSX */
910
911#ifdef CONFIG_SPE
912 /* SPE regs are not checkpointed with TM, so this section is
913 * simply the same as in restore_user_regs().
914 */
915 regs->msr &= ~MSR_SPE;
916 if (msr & MSR_SPE) {
917 if (__copy_from_user(current->thread.evr, &sr->mc_vregs,
918 ELF_NEVRREG * sizeof(u32)))
919 return 1;
920 } else if (current->thread.used_spe)
921 memset(current->thread.evr, 0, ELF_NEVRREG * sizeof(u32));
922
923 /* Always get SPEFSCR back */
924 if (__get_user(current->thread.spefscr, (u32 __user *)&sr->mc_vregs
925 + ELF_NEVRREG))
926 return 1;
927#endif /* CONFIG_SPE */
928
929 /* Now, recheckpoint. This loads up all of the checkpointed (older)
930 * registers, including FP and V[S]Rs. After recheckpointing, the
931 * transactional versions should be loaded.
932 */
933 tm_enable();
934 /* This loads the checkpointed FP/VEC state, if used */
935 tm_recheckpoint(&current->thread, msr);
936 /* The task has moved into TM state S, so ensure MSR reflects this */
937 regs->msr = (regs->msr & ~MSR_TS_MASK) | MSR_TS_S;
938
939 /* This loads the speculative FP/VEC state, if used */
940 if (msr & MSR_FP) {
941 do_load_up_transact_fpu(&current->thread);
942 regs->msr |= (MSR_FP | current->thread.fpexc_mode);
943 }
944 if (msr & MSR_VEC) {
945 do_load_up_transact_altivec(&current->thread);
946 regs->msr |= MSR_VEC;
947 }
948
949 return 0;
950}
951#endif
952
591#ifdef CONFIG_PPC64 953#ifdef CONFIG_PPC64
592long compat_sys_rt_sigaction(int sig, const struct sigaction32 __user *act, 954long compat_sys_rt_sigaction(int sig, const struct sigaction32 __user *act,
593 struct sigaction32 __user *oact, size_t sigsetsize) 955 struct sigaction32 __user *oact, size_t sigsetsize)
@@ -827,6 +1189,8 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
827 struct mcontext __user *frame; 1189 struct mcontext __user *frame;
828 void __user *addr; 1190 void __user *addr;
829 unsigned long newsp = 0; 1191 unsigned long newsp = 0;
1192 int sigret;
1193 unsigned long tramp;
830 1194
831 /* Set up Signal Frame */ 1195 /* Set up Signal Frame */
832 /* Put a Real Time Context onto stack */ 1196 /* Put a Real Time Context onto stack */
@@ -838,7 +1202,6 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
838 /* Put the siginfo & fill in most of the ucontext */ 1202 /* Put the siginfo & fill in most of the ucontext */
839 if (copy_siginfo_to_user(&rt_sf->info, info) 1203 if (copy_siginfo_to_user(&rt_sf->info, info)
840 || __put_user(0, &rt_sf->uc.uc_flags) 1204 || __put_user(0, &rt_sf->uc.uc_flags)
841 || __put_user(0, &rt_sf->uc.uc_link)
842 || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp) 1205 || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
843 || __put_user(sas_ss_flags(regs->gpr[1]), 1206 || __put_user(sas_ss_flags(regs->gpr[1]),
844 &rt_sf->uc.uc_stack.ss_flags) 1207 &rt_sf->uc.uc_stack.ss_flags)
@@ -852,14 +1215,37 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
852 frame = &rt_sf->uc.uc_mcontext; 1215 frame = &rt_sf->uc.uc_mcontext;
853 addr = frame; 1216 addr = frame;
854 if (vdso32_rt_sigtramp && current->mm->context.vdso_base) { 1217 if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
855 if (save_user_regs(regs, frame, 0, 1)) 1218 sigret = 0;
856 goto badframe; 1219 tramp = current->mm->context.vdso_base + vdso32_rt_sigtramp;
857 regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
858 } else { 1220 } else {
859 if (save_user_regs(regs, frame, __NR_rt_sigreturn, 1)) 1221 sigret = __NR_rt_sigreturn;
1222 tramp = (unsigned long) frame->tramp;
1223 }
1224
1225#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1226 if (MSR_TM_ACTIVE(regs->msr)) {
1227 if (save_tm_user_regs(regs, &rt_sf->uc.uc_mcontext,
1228 &rt_sf->uc_transact.uc_mcontext, sigret))
860 goto badframe; 1229 goto badframe;
861 regs->link = (unsigned long) frame->tramp;
862 } 1230 }
1231 else
1232#endif
1233 if (save_user_regs(regs, frame, sigret, 1))
1234 goto badframe;
1235 regs->link = tramp;
1236
1237#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1238 if (MSR_TM_ACTIVE(regs->msr)) {
1239 if (__put_user((unsigned long)&rt_sf->uc_transact,
1240 &rt_sf->uc.uc_link)
1241 || __put_user(to_user_ptr(&rt_sf->uc_transact.uc_mcontext),
1242 &rt_sf->uc_transact.uc_regs))
1243 goto badframe;
1244 }
1245 else
1246#endif
1247 if (__put_user(0, &rt_sf->uc.uc_link))
1248 goto badframe;
863 1249
864 current->thread.fpscr.val = 0; /* turn off all fp exceptions */ 1250 current->thread.fpscr.val = 0; /* turn off all fp exceptions */
865 1251
@@ -878,6 +1264,13 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
878 regs->nip = (unsigned long) ka->sa.sa_handler; 1264 regs->nip = (unsigned long) ka->sa.sa_handler;
879 /* enter the signal handler in big-endian mode */ 1265 /* enter the signal handler in big-endian mode */
880 regs->msr &= ~MSR_LE; 1266 regs->msr &= ~MSR_LE;
1267#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1268 /* Remove TM bits from thread's MSR. The MSR in the sigcontext
1269 * just indicates to userland that we were doing a transaction, but we
1270 * don't want to return in transactional state:
1271 */
1272 regs->msr &= ~MSR_TS_MASK;
1273#endif
881 return 1; 1274 return 1;
882 1275
883badframe: 1276badframe:
@@ -925,6 +1318,35 @@ static int do_setcontext(struct ucontext __user *ucp, struct pt_regs *regs, int
925 return 0; 1318 return 0;
926} 1319}
927 1320
1321#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1322static int do_setcontext_tm(struct ucontext __user *ucp,
1323 struct ucontext __user *tm_ucp,
1324 struct pt_regs *regs)
1325{
1326 sigset_t set;
1327 struct mcontext __user *mcp;
1328 struct mcontext __user *tm_mcp;
1329 u32 cmcp;
1330 u32 tm_cmcp;
1331
1332 if (get_sigset_t(&set, &ucp->uc_sigmask))
1333 return -EFAULT;
1334
1335 if (__get_user(cmcp, &ucp->uc_regs) ||
1336 __get_user(tm_cmcp, &tm_ucp->uc_regs))
1337 return -EFAULT;
1338 mcp = (struct mcontext __user *)(u64)cmcp;
1339 tm_mcp = (struct mcontext __user *)(u64)tm_cmcp;
1340 /* no need to check access_ok(mcp), since mcp < 4GB */
1341
1342 set_current_blocked(&set);
1343 if (restore_tm_user_regs(regs, mcp, tm_mcp))
1344 return -EFAULT;
1345
1346 return 0;
1347}
1348#endif
1349
928long sys_swapcontext(struct ucontext __user *old_ctx, 1350long sys_swapcontext(struct ucontext __user *old_ctx,
929 struct ucontext __user *new_ctx, 1351 struct ucontext __user *new_ctx,
930 int ctx_size, int r6, int r7, int r8, struct pt_regs *regs) 1352 int ctx_size, int r6, int r7, int r8, struct pt_regs *regs)
@@ -1020,7 +1442,12 @@ long sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
1020 struct pt_regs *regs) 1442 struct pt_regs *regs)
1021{ 1443{
1022 struct rt_sigframe __user *rt_sf; 1444 struct rt_sigframe __user *rt_sf;
1023 1445#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1446 struct ucontext __user *uc_transact;
1447 unsigned long msr_hi;
1448 unsigned long tmp;
1449 int tm_restore = 0;
1450#endif
1024 /* Always make any pending restarted system calls return -EINTR */ 1451 /* Always make any pending restarted system calls return -EINTR */
1025 current_thread_info()->restart_block.fn = do_no_restart_syscall; 1452 current_thread_info()->restart_block.fn = do_no_restart_syscall;
1026 1453
@@ -1028,6 +1455,34 @@ long sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
1028 (regs->gpr[1] + __SIGNAL_FRAMESIZE + 16); 1455 (regs->gpr[1] + __SIGNAL_FRAMESIZE + 16);
1029 if (!access_ok(VERIFY_READ, rt_sf, sizeof(*rt_sf))) 1456 if (!access_ok(VERIFY_READ, rt_sf, sizeof(*rt_sf)))
1030 goto bad; 1457 goto bad;
1458#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1459 if (__get_user(tmp, &rt_sf->uc.uc_link))
1460 goto bad;
1461 uc_transact = (struct ucontext __user *)(uintptr_t)tmp;
1462 if (uc_transact) {
1463 u32 cmcp;
1464 struct mcontext __user *mcp;
1465
1466 if (__get_user(cmcp, &uc_transact->uc_regs))
1467 return -EFAULT;
1468 mcp = (struct mcontext __user *)(u64)cmcp;
1469 /* The top 32 bits of the MSR are stashed in the transactional
1470 * ucontext. */
1471 if (__get_user(msr_hi, &mcp->mc_gregs[PT_MSR]))
1472 goto bad;
1473
1474 if (MSR_TM_SUSPENDED(msr_hi<<32)) {
1475 /* We only recheckpoint on return if we're
1476 * transaction.
1477 */
1478 tm_restore = 1;
1479 if (do_setcontext_tm(&rt_sf->uc, uc_transact, regs))
1480 goto bad;
1481 }
1482 }
1483 if (!tm_restore)
1484 /* Fall through, for non-TM restore */
1485#endif
1031 if (do_setcontext(&rt_sf->uc, regs, 1)) 1486 if (do_setcontext(&rt_sf->uc, regs, 1))
1032 goto bad; 1487 goto bad;
1033 1488
@@ -1179,6 +1634,8 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
1179 struct sigcontext __user *sc; 1634 struct sigcontext __user *sc;
1180 struct sigframe __user *frame; 1635 struct sigframe __user *frame;
1181 unsigned long newsp = 0; 1636 unsigned long newsp = 0;
1637 int sigret;
1638 unsigned long tramp;
1182 1639
1183 /* Set up Signal Frame */ 1640 /* Set up Signal Frame */
1184 frame = get_sigframe(ka, regs, sizeof(*frame), 1); 1641 frame = get_sigframe(ka, regs, sizeof(*frame), 1);
@@ -1201,14 +1658,25 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
1201 goto badframe; 1658 goto badframe;
1202 1659
1203 if (vdso32_sigtramp && current->mm->context.vdso_base) { 1660 if (vdso32_sigtramp && current->mm->context.vdso_base) {
1204 if (save_user_regs(regs, &frame->mctx, 0, 1)) 1661 sigret = 0;
1205 goto badframe; 1662 tramp = current->mm->context.vdso_base + vdso32_sigtramp;
1206 regs->link = current->mm->context.vdso_base + vdso32_sigtramp;
1207 } else { 1663 } else {
1208 if (save_user_regs(regs, &frame->mctx, __NR_sigreturn, 1)) 1664 sigret = __NR_sigreturn;
1665 tramp = (unsigned long) frame->mctx.tramp;
1666 }
1667
1668#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1669 if (MSR_TM_ACTIVE(regs->msr)) {
1670 if (save_tm_user_regs(regs, &frame->mctx, &frame->mctx_transact,
1671 sigret))
1209 goto badframe; 1672 goto badframe;
1210 regs->link = (unsigned long) frame->mctx.tramp;
1211 } 1673 }
1674 else
1675#endif
1676 if (save_user_regs(regs, &frame->mctx, sigret, 1))
1677 goto badframe;
1678
1679 regs->link = tramp;
1212 1680
1213 current->thread.fpscr.val = 0; /* turn off all fp exceptions */ 1681 current->thread.fpscr.val = 0; /* turn off all fp exceptions */
1214 1682
@@ -1223,7 +1691,13 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
1223 regs->nip = (unsigned long) ka->sa.sa_handler; 1691 regs->nip = (unsigned long) ka->sa.sa_handler;
1224 /* enter the signal handler in big-endian mode */ 1692 /* enter the signal handler in big-endian mode */
1225 regs->msr &= ~MSR_LE; 1693 regs->msr &= ~MSR_LE;
1226 1694#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1695 /* Remove TM bits from thread's MSR. The MSR in the sigcontext
1696 * just indicates to userland that we were doing a transaction, but we
1697 * don't want to return in transactional state:
1698 */
1699 regs->msr &= ~MSR_TS_MASK;
1700#endif
1227 return 1; 1701 return 1;
1228 1702
1229badframe: 1703badframe:
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 1ca045d44324..7a76ee48a952 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -34,6 +34,7 @@
34#include <asm/syscalls.h> 34#include <asm/syscalls.h>
35#include <asm/vdso.h> 35#include <asm/vdso.h>
36#include <asm/switch_to.h> 36#include <asm/switch_to.h>
37#include <asm/tm.h>
37 38
38#include "signal.h" 39#include "signal.h"
39 40
@@ -56,6 +57,9 @@
56struct rt_sigframe { 57struct rt_sigframe {
57 /* sys_rt_sigreturn requires the ucontext be the first field */ 58 /* sys_rt_sigreturn requires the ucontext be the first field */
58 struct ucontext uc; 59 struct ucontext uc;
60#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
61 struct ucontext uc_transact;
62#endif
59 unsigned long _unused[2]; 63 unsigned long _unused[2];
60 unsigned int tramp[TRAMP_SIZE]; 64 unsigned int tramp[TRAMP_SIZE];
61 struct siginfo __user *pinfo; 65 struct siginfo __user *pinfo;
@@ -145,6 +149,145 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
145 return err; 149 return err;
146} 150}
147 151
152#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
153/*
154 * As above, but Transactional Memory is in use, so deliver sigcontexts
155 * containing checkpointed and transactional register states.
156 *
157 * To do this, we treclaim to gather both sets of registers and set up the
158 * 'normal' sigcontext registers with rolled-back register values such that a
159 * simple signal handler sees a correct checkpointed register state.
160 * If interested, a TM-aware sighandler can examine the transactional registers
161 * in the 2nd sigcontext to determine the real origin of the signal.
162 */
163static long setup_tm_sigcontexts(struct sigcontext __user *sc,
164 struct sigcontext __user *tm_sc,
165 struct pt_regs *regs,
166 int signr, sigset_t *set, unsigned long handler)
167{
168 /* When CONFIG_ALTIVEC is set, we _always_ setup v_regs even if the
169 * process never used altivec yet (MSR_VEC is zero in pt_regs of
170 * the context). This is very important because we must ensure we
171 * don't lose the VRSAVE content that may have been set prior to
172 * the process doing its first vector operation
173 * Userland shall check AT_HWCAP to know wether it can rely on the
174 * v_regs pointer or not.
175 */
176#ifdef CONFIG_ALTIVEC
177 elf_vrreg_t __user *v_regs = (elf_vrreg_t __user *)
178 (((unsigned long)sc->vmx_reserve + 15) & ~0xful);
179 elf_vrreg_t __user *tm_v_regs = (elf_vrreg_t __user *)
180 (((unsigned long)tm_sc->vmx_reserve + 15) & ~0xful);
181#endif
182 unsigned long msr = regs->msr;
183 long err = 0;
184
185 BUG_ON(!MSR_TM_ACTIVE(regs->msr));
186
187 /* tm_reclaim rolls back all reg states, saving checkpointed (older)
188 * GPRs to thread.ckpt_regs and (if used) FPRs to (newer)
189 * thread.transact_fp and/or VRs to (newer) thread.transact_vr.
190 * THEN we save out FP/VRs, if necessary, to the checkpointed (older)
191 * thread.fr[]/vr[]s. The transactional (newer) GPRs are on the
192 * stack, in *regs.
193 */
194 tm_enable();
195 tm_reclaim(&current->thread, msr, TM_CAUSE_SIGNAL);
196
197 flush_fp_to_thread(current);
198
199#ifdef CONFIG_ALTIVEC
200 err |= __put_user(v_regs, &sc->v_regs);
201 err |= __put_user(tm_v_regs, &tm_sc->v_regs);
202
203 /* save altivec registers */
204 if (current->thread.used_vr) {
205 flush_altivec_to_thread(current);
206 /* Copy 33 vec registers (vr0..31 and vscr) to the stack */
207 err |= __copy_to_user(v_regs, current->thread.vr,
208 33 * sizeof(vector128));
209 /* If VEC was enabled there are transactional VRs valid too,
210 * else they're a copy of the checkpointed VRs.
211 */
212 if (msr & MSR_VEC)
213 err |= __copy_to_user(tm_v_regs,
214 current->thread.transact_vr,
215 33 * sizeof(vector128));
216 else
217 err |= __copy_to_user(tm_v_regs,
218 current->thread.vr,
219 33 * sizeof(vector128));
220
221 /* set MSR_VEC in the MSR value in the frame to indicate
222 * that sc->v_reg contains valid data.
223 */
224 msr |= MSR_VEC;
225 }
226 /* We always copy to/from vrsave, it's 0 if we don't have or don't
227 * use altivec.
228 */
229 err |= __put_user(current->thread.vrsave, (u32 __user *)&v_regs[33]);
230 if (msr & MSR_VEC)
231 err |= __put_user(current->thread.transact_vrsave,
232 (u32 __user *)&tm_v_regs[33]);
233 else
234 err |= __put_user(current->thread.vrsave,
235 (u32 __user *)&tm_v_regs[33]);
236
237#else /* CONFIG_ALTIVEC */
238 err |= __put_user(0, &sc->v_regs);
239 err |= __put_user(0, &tm_sc->v_regs);
240#endif /* CONFIG_ALTIVEC */
241
242 /* copy fpr regs and fpscr */
243 err |= copy_fpr_to_user(&sc->fp_regs, current);
244 if (msr & MSR_FP)
245 err |= copy_transact_fpr_to_user(&tm_sc->fp_regs, current);
246 else
247 err |= copy_fpr_to_user(&tm_sc->fp_regs, current);
248
249#ifdef CONFIG_VSX
250 /*
251 * Copy VSX low doubleword to local buffer for formatting,
252 * then out to userspace. Update v_regs to point after the
253 * VMX data.
254 */
255 if (current->thread.used_vsr) {
256 __giveup_vsx(current);
257 v_regs += ELF_NVRREG;
258 tm_v_regs += ELF_NVRREG;
259
260 err |= copy_vsx_to_user(v_regs, current);
261
262 if (msr & MSR_VSX)
263 err |= copy_transact_vsx_to_user(tm_v_regs, current);
264 else
265 err |= copy_vsx_to_user(tm_v_regs, current);
266
267 /* set MSR_VSX in the MSR value in the frame to
268 * indicate that sc->vs_reg) contains valid data.
269 */
270 msr |= MSR_VSX;
271 }
272#endif /* CONFIG_VSX */
273
274 err |= __put_user(&sc->gp_regs, &sc->regs);
275 err |= __put_user(&tm_sc->gp_regs, &tm_sc->regs);
276 WARN_ON(!FULL_REGS(regs));
277 err |= __copy_to_user(&tm_sc->gp_regs, regs, GP_REGS_SIZE);
278 err |= __copy_to_user(&sc->gp_regs,
279 &current->thread.ckpt_regs, GP_REGS_SIZE);
280 err |= __put_user(msr, &tm_sc->gp_regs[PT_MSR]);
281 err |= __put_user(msr, &sc->gp_regs[PT_MSR]);
282 err |= __put_user(signr, &sc->signal);
283 err |= __put_user(handler, &sc->handler);
284 if (set != NULL)
285 err |= __put_user(set->sig[0], &sc->oldmask);
286
287 return err;
288}
289#endif
290
148/* 291/*
149 * Restore the sigcontext from the signal frame. 292 * Restore the sigcontext from the signal frame.
150 */ 293 */
@@ -241,6 +384,153 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig,
241 return err; 384 return err;
242} 385}
243 386
387#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
388/*
389 * Restore the two sigcontexts from the frame of a transactional processes.
390 */
391
392static long restore_tm_sigcontexts(struct pt_regs *regs,
393 struct sigcontext __user *sc,
394 struct sigcontext __user *tm_sc)
395{
396#ifdef CONFIG_ALTIVEC
397 elf_vrreg_t __user *v_regs, *tm_v_regs;
398#endif
399 unsigned long err = 0;
400 unsigned long msr;
401#ifdef CONFIG_VSX
402 int i;
403#endif
404 /* copy the GPRs */
405 err |= __copy_from_user(regs->gpr, tm_sc->gp_regs, sizeof(regs->gpr));
406 err |= __copy_from_user(&current->thread.ckpt_regs, sc->gp_regs,
407 sizeof(regs->gpr));
408
409 /*
410 * TFHAR is restored from the checkpointed 'wound-back' ucontext's NIP.
411 * TEXASR was set by the signal delivery reclaim, as was TFIAR.
412 * Users doing anything abhorrent like thread-switching w/ signals for
413 * TM-Suspended code will have to back TEXASR/TFIAR up themselves.
414 * For the case of getting a signal and simply returning from it,
415 * we don't need to re-copy them here.
416 */
417 err |= __get_user(regs->nip, &tm_sc->gp_regs[PT_NIP]);
418 err |= __get_user(current->thread.tm_tfhar, &sc->gp_regs[PT_NIP]);
419
420 /* get MSR separately, transfer the LE bit if doing signal return */
421 err |= __get_user(msr, &sc->gp_regs[PT_MSR]);
422 regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE);
423
424 /* The following non-GPR non-FPR non-VR state is also checkpointed: */
425 err |= __get_user(regs->ctr, &tm_sc->gp_regs[PT_CTR]);
426 err |= __get_user(regs->link, &tm_sc->gp_regs[PT_LNK]);
427 err |= __get_user(regs->xer, &tm_sc->gp_regs[PT_XER]);
428 err |= __get_user(regs->ccr, &tm_sc->gp_regs[PT_CCR]);
429 err |= __get_user(current->thread.ckpt_regs.ctr,
430 &sc->gp_regs[PT_CTR]);
431 err |= __get_user(current->thread.ckpt_regs.link,
432 &sc->gp_regs[PT_LNK]);
433 err |= __get_user(current->thread.ckpt_regs.xer,
434 &sc->gp_regs[PT_XER]);
435 err |= __get_user(current->thread.ckpt_regs.ccr,
436 &sc->gp_regs[PT_CCR]);
437
438 /* These regs are not checkpointed; they can go in 'regs'. */
439 err |= __get_user(regs->trap, &sc->gp_regs[PT_TRAP]);
440 err |= __get_user(regs->dar, &sc->gp_regs[PT_DAR]);
441 err |= __get_user(regs->dsisr, &sc->gp_regs[PT_DSISR]);
442 err |= __get_user(regs->result, &sc->gp_regs[PT_RESULT]);
443
444 /*
445 * Do this before updating the thread state in
446 * current->thread.fpr/vr. That way, if we get preempted
447 * and another task grabs the FPU/Altivec, it won't be
448 * tempted to save the current CPU state into the thread_struct
449 * and corrupt what we are writing there.
450 */
451 discard_lazy_cpu_state();
452
453 /*
454 * Force reload of FP/VEC.
455 * This has to be done before copying stuff into current->thread.fpr/vr
456 * for the reasons explained in the previous comment.
457 */
458 regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1 | MSR_VEC | MSR_VSX);
459
460#ifdef CONFIG_ALTIVEC
461 err |= __get_user(v_regs, &sc->v_regs);
462 err |= __get_user(tm_v_regs, &tm_sc->v_regs);
463 if (err)
464 return err;
465 if (v_regs && !access_ok(VERIFY_READ, v_regs, 34 * sizeof(vector128)))
466 return -EFAULT;
467 if (tm_v_regs && !access_ok(VERIFY_READ,
468 tm_v_regs, 34 * sizeof(vector128)))
469 return -EFAULT;
470 /* Copy 33 vec registers (vr0..31 and vscr) from the stack */
471 if (v_regs != 0 && tm_v_regs != 0 && (msr & MSR_VEC) != 0) {
472 err |= __copy_from_user(current->thread.vr, v_regs,
473 33 * sizeof(vector128));
474 err |= __copy_from_user(current->thread.transact_vr, tm_v_regs,
475 33 * sizeof(vector128));
476 }
477 else if (current->thread.used_vr) {
478 memset(current->thread.vr, 0, 33 * sizeof(vector128));
479 memset(current->thread.transact_vr, 0, 33 * sizeof(vector128));
480 }
481 /* Always get VRSAVE back */
482 if (v_regs != 0 && tm_v_regs != 0) {
483 err |= __get_user(current->thread.vrsave,
484 (u32 __user *)&v_regs[33]);
485 err |= __get_user(current->thread.transact_vrsave,
486 (u32 __user *)&tm_v_regs[33]);
487 }
488 else {
489 current->thread.vrsave = 0;
490 current->thread.transact_vrsave = 0;
491 }
492#endif /* CONFIG_ALTIVEC */
493 /* restore floating point */
494 err |= copy_fpr_from_user(current, &sc->fp_regs);
495 err |= copy_transact_fpr_from_user(current, &tm_sc->fp_regs);
496#ifdef CONFIG_VSX
497 /*
498 * Get additional VSX data. Update v_regs to point after the
499 * VMX data. Copy VSX low doubleword from userspace to local
500 * buffer for formatting, then into the taskstruct.
501 */
502 if (v_regs && ((msr & MSR_VSX) != 0)) {
503 v_regs += ELF_NVRREG;
504 tm_v_regs += ELF_NVRREG;
505 err |= copy_vsx_from_user(current, v_regs);
506 err |= copy_transact_vsx_from_user(current, tm_v_regs);
507 } else {
508 for (i = 0; i < 32 ; i++) {
509 current->thread.fpr[i][TS_VSRLOWOFFSET] = 0;
510 current->thread.transact_fpr[i][TS_VSRLOWOFFSET] = 0;
511 }
512 }
513#endif
514 tm_enable();
515 /* This loads the checkpointed FP/VEC state, if used */
516 tm_recheckpoint(&current->thread, msr);
517 /* The task has moved into TM state S, so ensure MSR reflects this: */
518 regs->msr = (regs->msr & ~MSR_TS_MASK) | __MASK(33);
519
520 /* This loads the speculative FP/VEC state, if used */
521 if (msr & MSR_FP) {
522 do_load_up_transact_fpu(&current->thread);
523 regs->msr |= (MSR_FP | current->thread.fpexc_mode);
524 }
525 if (msr & MSR_VEC) {
526 do_load_up_transact_altivec(&current->thread);
527 regs->msr |= MSR_VEC;
528 }
529
530 return err;
531}
532#endif
533
244/* 534/*
245 * Setup the trampoline code on the stack 535 * Setup the trampoline code on the stack
246 */ 536 */
@@ -355,6 +645,9 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
355{ 645{
356 struct ucontext __user *uc = (struct ucontext __user *)regs->gpr[1]; 646 struct ucontext __user *uc = (struct ucontext __user *)regs->gpr[1];
357 sigset_t set; 647 sigset_t set;
648#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
649 unsigned long msr;
650#endif
358 651
359 /* Always make any pending restarted system calls return -EINTR */ 652 /* Always make any pending restarted system calls return -EINTR */
360 current_thread_info()->restart_block.fn = do_no_restart_syscall; 653 current_thread_info()->restart_block.fn = do_no_restart_syscall;
@@ -365,6 +658,21 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
365 if (__copy_from_user(&set, &uc->uc_sigmask, sizeof(set))) 658 if (__copy_from_user(&set, &uc->uc_sigmask, sizeof(set)))
366 goto badframe; 659 goto badframe;
367 set_current_blocked(&set); 660 set_current_blocked(&set);
661#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
662 if (__get_user(msr, &uc->uc_mcontext.gp_regs[PT_MSR]))
663 goto badframe;
664 if (MSR_TM_SUSPENDED(msr)) {
665 /* We recheckpoint on return. */
666 struct ucontext __user *uc_transact;
667 if (__get_user(uc_transact, &uc->uc_link))
668 goto badframe;
669 if (restore_tm_sigcontexts(regs, &uc->uc_mcontext,
670 &uc_transact->uc_mcontext))
671 goto badframe;
672 }
673 else
674 /* Fall through, for non-TM restore */
675#endif
368 if (restore_sigcontext(regs, NULL, 1, &uc->uc_mcontext)) 676 if (restore_sigcontext(regs, NULL, 1, &uc->uc_mcontext))
369 goto badframe; 677 goto badframe;
370 678
@@ -415,19 +723,42 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
415 723
416 /* Create the ucontext. */ 724 /* Create the ucontext. */
417 err |= __put_user(0, &frame->uc.uc_flags); 725 err |= __put_user(0, &frame->uc.uc_flags);
418 err |= __put_user(0, &frame->uc.uc_link);
419 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); 726 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
420 err |= __put_user(sas_ss_flags(regs->gpr[1]), 727 err |= __put_user(sas_ss_flags(regs->gpr[1]),
421 &frame->uc.uc_stack.ss_flags); 728 &frame->uc.uc_stack.ss_flags);
422 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 729 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
423 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, signr, NULL, 730#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
424 (unsigned long)ka->sa.sa_handler, 1); 731 if (MSR_TM_ACTIVE(regs->msr)) {
732 /* The ucontext_t passed to userland points to the second
733 * ucontext_t (for transactional state) with its uc_link ptr.
734 */
735 err |= __put_user(&frame->uc_transact, &frame->uc.uc_link);
736 err |= setup_tm_sigcontexts(&frame->uc.uc_mcontext,
737 &frame->uc_transact.uc_mcontext,
738 regs, signr,
739 NULL,
740 (unsigned long)ka->sa.sa_handler);
741 } else
742#endif
743 {
744 err |= __put_user(0, &frame->uc.uc_link);
745 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, signr,
746 NULL, (unsigned long)ka->sa.sa_handler,
747 1);
748 }
425 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 749 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
426 if (err) 750 if (err)
427 goto badframe; 751 goto badframe;
428 752
429 /* Make sure signal handler doesn't get spurious FP exceptions */ 753 /* Make sure signal handler doesn't get spurious FP exceptions */
430 current->thread.fpscr.val = 0; 754 current->thread.fpscr.val = 0;
755#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
756 /* Remove TM bits from thread's MSR. The MSR in the sigcontext
757 * just indicates to userland that we were doing a transaction, but we
758 * don't want to return in transactional state:
759 */
760 regs->msr &= ~MSR_TS_MASK;
761#endif
431 762
432 /* Set up to return from userspace. */ 763 /* Set up to return from userspace. */
433 if (vdso64_rt_sigtramp && current->mm->context.vdso_base) { 764 if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
diff --git a/arch/powerpc/kernel/tm.S b/arch/powerpc/kernel/tm.S
new file mode 100644
index 000000000000..84dbace657ce
--- /dev/null
+++ b/arch/powerpc/kernel/tm.S
@@ -0,0 +1,388 @@
1/*
2 * Transactional memory support routines to reclaim and recheckpoint
3 * transactional process state.
4 *
5 * Copyright 2012 Matt Evans & Michael Neuling, IBM Corporation.
6 */
7
8#include <asm/asm-offsets.h>
9#include <asm/ppc_asm.h>
10#include <asm/ppc-opcode.h>
11#include <asm/ptrace.h>
12#include <asm/reg.h>
13
14#ifdef CONFIG_VSX
15/* See fpu.S, this is very similar but to save/restore checkpointed FPRs/VSRs */
16#define __SAVE_32FPRS_VSRS_TRANSACT(n,c,base) \
17BEGIN_FTR_SECTION \
18 b 2f; \
19END_FTR_SECTION_IFSET(CPU_FTR_VSX); \
20 SAVE_32FPRS_TRANSACT(n,base); \
21 b 3f; \
222: SAVE_32VSRS_TRANSACT(n,c,base); \
233:
24/* ...and this is just plain borrowed from there. */
25#define __REST_32FPRS_VSRS(n,c,base) \
26BEGIN_FTR_SECTION \
27 b 2f; \
28END_FTR_SECTION_IFSET(CPU_FTR_VSX); \
29 REST_32FPRS(n,base); \
30 b 3f; \
312: REST_32VSRS(n,c,base); \
323:
33#else
34#define __SAVE_32FPRS_VSRS_TRANSACT(n,c,base) SAVE_32FPRS_TRANSACT(n, base)
35#define __REST_32FPRS_VSRS(n,c,base) REST_32FPRS(n, base)
36#endif
37#define SAVE_32FPRS_VSRS_TRANSACT(n,c,base) \
38 __SAVE_32FPRS_VSRS_TRANSACT(n,__REG_##c,__REG_##base)
39#define REST_32FPRS_VSRS(n,c,base) \
40 __REST_32FPRS_VSRS(n,__REG_##c,__REG_##base)
41
42/* Stack frame offsets for local variables. */
43#define TM_FRAME_L0 TM_FRAME_SIZE-16
44#define TM_FRAME_L1 TM_FRAME_SIZE-8
45#define STACK_PARAM(x) (48+((x)*8))
46
47
48/* In order to access the TM SPRs, TM must be enabled. So, do so: */
49_GLOBAL(tm_enable)
50 mfmsr r4
51 li r3, MSR_TM >> 32
52 sldi r3, r3, 32
53 and. r0, r4, r3
54 bne 1f
55 or r4, r4, r3
56 mtmsrd r4
571: blr
58
59_GLOBAL(tm_save_sprs)
60 mfspr r0, SPRN_TFHAR
61 std r0, THREAD_TM_TFHAR(r3)
62 mfspr r0, SPRN_TEXASR
63 std r0, THREAD_TM_TEXASR(r3)
64 mfspr r0, SPRN_TFIAR
65 std r0, THREAD_TM_TFIAR(r3)
66 blr
67
68_GLOBAL(tm_restore_sprs)
69 ld r0, THREAD_TM_TFHAR(r3)
70 mtspr SPRN_TFHAR, r0
71 ld r0, THREAD_TM_TEXASR(r3)
72 mtspr SPRN_TEXASR, r0
73 ld r0, THREAD_TM_TFIAR(r3)
74 mtspr SPRN_TFIAR, r0
75 blr
76
77 /* Passed an 8-bit failure cause as first argument. */
78_GLOBAL(tm_abort)
79 TABORT(R3)
80 blr
81
82
83/* void tm_reclaim(struct thread_struct *thread,
84 * unsigned long orig_msr,
85 * uint8_t cause)
86 *
87 * - Performs a full reclaim. This destroys outstanding
88 * transactions and updates thread->regs.tm_ckpt_* with the
89 * original checkpointed state. Note that thread->regs is
90 * unchanged.
91 * - FP regs are written back to thread->transact_fpr before
92 * reclaiming. These are the transactional (current) versions.
93 *
94 * Purpose is to both abort transactions of, and preserve the state of,
95 * a transactions at a context switch. We preserve/restore both sets of process
96 * state to restore them when the thread's scheduled again. We continue in
97 * userland as though nothing happened, but when the transaction is resumed
98 * they will abort back to the checkpointed state we save out here.
99 *
100 * Call with IRQs off, stacks get all out of sync for some periods in here!
101 */
102_GLOBAL(tm_reclaim)
103 mfcr r6
104 mflr r0
105 std r6, 8(r1)
106 std r0, 16(r1)
107 std r2, 40(r1)
108 stdu r1, -TM_FRAME_SIZE(r1)
109
110 /* We've a struct pt_regs at [r1+STACK_FRAME_OVERHEAD]. */
111
112 std r3, STACK_PARAM(0)(r1)
113 SAVE_NVGPRS(r1)
114
115 mfmsr r14
116 mr r15, r14
117 ori r15, r15, MSR_FP
118 oris r15, r15, MSR_VEC@h
119#ifdef CONFIG_VSX
120 BEGIN_FTR_SECTION
121 oris r15,r15, MSR_VSX@h
122 END_FTR_SECTION_IFSET(CPU_FTR_VSX)
123#endif
124 mtmsrd r15
125 std r14, TM_FRAME_L0(r1)
126
127 /* Stash the stack pointer away for use after reclaim */
128 std r1, PACAR1(r13)
129
130 /* ******************** FPR/VR/VSRs ************
131 * Before reclaiming, capture the current/transactional FPR/VR
132 * versions /if used/.
133 *
134 * (If VSX used, FP and VMX are implied. Or, we don't need to look
135 * at MSR.VSX as copying FP regs if .FP, vector regs if .VMX covers it.)
136 *
137 * We're passed the thread's MSR as parameter 2.
138 *
139 * We enabled VEC/FP/VSX in the msr above, so we can execute these
140 * instructions!
141 */
142 andis. r0, r4, MSR_VEC@h
143 beq dont_backup_vec
144
145 SAVE_32VRS_TRANSACT(0, r6, r3) /* r6 scratch, r3 thread */
146 mfvscr vr0
147 li r6, THREAD_TRANSACT_VSCR
148 stvx vr0, r3, r6
149 mfspr r0, SPRN_VRSAVE
150 std r0, THREAD_TRANSACT_VRSAVE(r3)
151
152dont_backup_vec:
153 andi. r0, r4, MSR_FP
154 beq dont_backup_fp
155
156 SAVE_32FPRS_VSRS_TRANSACT(0, R6, R3) /* r6 scratch, r3 thread */
157
158 mffs fr0
159 stfd fr0,THREAD_TRANSACT_FPSCR(r3)
160
161dont_backup_fp:
162 /* The moment we treclaim, ALL of our GPRs will switch
163 * to user register state. (FPRs, CCR etc. also!)
164 * Use an sprg and a tm_scratch in the PACA to shuffle.
165 */
166 TRECLAIM(R5) /* Cause in r5 */
167
168 /* ******************** GPRs ******************** */
169 /* Stash the checkpointed r13 away in the scratch SPR and get the real
170 * paca
171 */
172 SET_SCRATCH0(r13)
173 GET_PACA(r13)
174
175 /* Stash the checkpointed r1 away in paca tm_scratch and get the real
176 * stack pointer back
177 */
178 std r1, PACATMSCRATCH(r13)
179 ld r1, PACAR1(r13)
180
181 /* Now get some more GPRS free */
182 std r7, GPR7(r1) /* Temporary stash */
183 std r12, GPR12(r1) /* '' '' '' */
184 ld r12, STACK_PARAM(0)(r1) /* Param 0, thread_struct * */
185
186 addi r7, r12, PT_CKPT_REGS /* Thread's ckpt_regs */
187
188 /* Make r7 look like an exception frame so that we
189 * can use the neat GPRx(n) macros. r7 is NOT a pt_regs ptr!
190 */
191 subi r7, r7, STACK_FRAME_OVERHEAD
192
193 /* Sync the userland GPRs 2-12, 14-31 to thread->regs: */
194 SAVE_GPR(0, r7) /* user r0 */
195 SAVE_GPR(2, r7) /* user r2 */
196 SAVE_4GPRS(3, r7) /* user r3-r6 */
197 SAVE_4GPRS(8, r7) /* user r8-r11 */
198 ld r3, PACATMSCRATCH(r13) /* user r1 */
199 ld r4, GPR7(r1) /* user r7 */
200 ld r5, GPR12(r1) /* user r12 */
201 GET_SCRATCH0(6) /* user r13 */
202 std r3, GPR1(r7)
203 std r4, GPR7(r7)
204 std r5, GPR12(r7)
205 std r6, GPR13(r7)
206
207 SAVE_NVGPRS(r7) /* user r14-r31 */
208
209 /* ******************** NIP ******************** */
210 mfspr r3, SPRN_TFHAR
211 std r3, _NIP(r7) /* Returns to failhandler */
212 /* The checkpointed NIP is ignored when rescheduling/rechkpting,
213 * but is used in signal return to 'wind back' to the abort handler.
214 */
215
216 /* ******************** CR,LR,CCR,MSR ********** */
217 mfctr r3
218 mflr r4
219 mfcr r5
220 mfxer r6
221
222 std r3, _CTR(r7)
223 std r4, _LINK(r7)
224 std r5, _CCR(r7)
225 std r6, _XER(r7)
226
227 /* MSR and flags: We don't change CRs, and we don't need to alter
228 * MSR.
229 */
230
231 /* TM regs, incl TEXASR -- these live in thread_struct. Note they've
232 * been updated by the treclaim, to explain to userland the failure
233 * cause (aborted).
234 */
235 mfspr r0, SPRN_TEXASR
236 mfspr r3, SPRN_TFHAR
237 mfspr r4, SPRN_TFIAR
238 std r0, THREAD_TM_TEXASR(r12)
239 std r3, THREAD_TM_TFHAR(r12)
240 std r4, THREAD_TM_TFIAR(r12)
241
242 /* AMR and PPR are checkpointed too, but are unsupported by Linux. */
243
244 /* Restore original MSR/IRQ state & clear TM mode */
245 ld r14, TM_FRAME_L0(r1) /* Orig MSR */
246 li r15, 0
247 rldimi r14, r15, MSR_TS_LG, (63-MSR_TS_LG)-1
248 mtmsrd r14
249
250 REST_NVGPRS(r1)
251
252 addi r1, r1, TM_FRAME_SIZE
253 ld r4, 8(r1)
254 ld r0, 16(r1)
255 mtcr r4
256 mtlr r0
257 ld r2, 40(r1)
258 blr
259
260
261 /* void tm_recheckpoint(struct thread_struct *thread,
262 * unsigned long orig_msr)
263 * - Restore the checkpointed register state saved by tm_reclaim
264 * when we switch_to a process.
265 *
266 * Call with IRQs off, stacks get all out of sync for
267 * some periods in here!
268 */
269_GLOBAL(tm_recheckpoint)
270 mfcr r5
271 mflr r0
272 std r5, 8(r1)
273 std r0, 16(r1)
274 std r2, 40(r1)
275 stdu r1, -TM_FRAME_SIZE(r1)
276
277 /* We've a struct pt_regs at [r1+STACK_FRAME_OVERHEAD].
278 * This is used for backing up the NVGPRs:
279 */
280 SAVE_NVGPRS(r1)
281
282 std r1, PACAR1(r13)
283
284 /* Load complete register state from ts_ckpt* registers */
285
286 addi r7, r3, PT_CKPT_REGS /* Thread's ckpt_regs */
287
288 /* Make r7 look like an exception frame so that we
289 * can use the neat GPRx(n) macros. r7 is now NOT a pt_regs ptr!
290 */
291 subi r7, r7, STACK_FRAME_OVERHEAD
292
293 SET_SCRATCH0(r1)
294
295 mfmsr r6
296 /* R4 = original MSR to indicate whether thread used FP/Vector etc. */
297
298 /* Enable FP/vec in MSR if necessary! */
299 lis r5, MSR_VEC@h
300 ori r5, r5, MSR_FP
301 and. r5, r4, r5
302 beq restore_gprs /* if neither, skip both */
303
304#ifdef CONFIG_VSX
305 BEGIN_FTR_SECTION
306 oris r5, r5, MSR_VSX@h
307 END_FTR_SECTION_IFSET(CPU_FTR_VSX)
308#endif
309 or r5, r6, r5 /* Set MSR.FP+.VSX/.VEC */
310 mtmsr r5
311
312 /* FP and VEC registers: These are recheckpointed from thread.fpr[]
313 * and thread.vr[] respectively. The thread.transact_fpr[] version
314 * is more modern, and will be loaded subsequently by any FPUnavailable
315 * trap.
316 */
317 andis. r0, r4, MSR_VEC@h
318 beq dont_restore_vec
319
320 li r5, THREAD_VSCR
321 lvx vr0, r3, r5
322 mtvscr vr0
323 REST_32VRS(0, r5, r3) /* r5 scratch, r3 THREAD ptr */
324 ld r5, THREAD_VRSAVE(r3)
325 mtspr SPRN_VRSAVE, r5
326
327dont_restore_vec:
328 andi. r0, r4, MSR_FP
329 beq dont_restore_fp
330
331 lfd fr0, THREAD_FPSCR(r3)
332 MTFSF_L(fr0)
333 REST_32FPRS_VSRS(0, R4, R3)
334
335dont_restore_fp:
336 mtmsr r6 /* FP/Vec off again! */
337
338restore_gprs:
339 /* ******************** CR,LR,CCR,MSR ********** */
340 ld r3, _CTR(r7)
341 ld r4, _LINK(r7)
342 ld r5, _CCR(r7)
343 ld r6, _XER(r7)
344
345 mtctr r3
346 mtlr r4
347 mtcr r5
348 mtxer r6
349
350 /* MSR and flags: We don't change CRs, and we don't need to alter
351 * MSR.
352 */
353
354 REST_4GPRS(0, r7) /* GPR0-3 */
355 REST_GPR(4, r7) /* GPR4-6 */
356 REST_GPR(5, r7)
357 REST_GPR(6, r7)
358 REST_4GPRS(8, r7) /* GPR8-11 */
359 REST_2GPRS(12, r7) /* GPR12-13 */
360
361 REST_NVGPRS(r7) /* GPR14-31 */
362
363 ld r7, GPR7(r7) /* GPR7 */
364
365 /* Commit register state as checkpointed state: */
366 TRECHKPT
367
368 /* Our transactional state has now changed.
369 *
370 * Now just get out of here. Transactional (current) state will be
371 * updated once restore is called on the return path in the _switch-ed
372 * -to process.
373 */
374
375 GET_PACA(r13)
376 GET_SCRATCH0(r1)
377
378 REST_NVGPRS(r1)
379
380 addi r1, r1, TM_FRAME_SIZE
381 ld r4, 8(r1)
382 ld r0, 16(r1)
383 mtcr r4
384 mtlr r0
385 ld r2, 40(r1)
386 blr
387
388 /* ****************************************************************** */
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index a008cf5c0fce..f9b751b29558 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -58,6 +58,7 @@
58#include <asm/rio.h> 58#include <asm/rio.h>
59#include <asm/fadump.h> 59#include <asm/fadump.h>
60#include <asm/switch_to.h> 60#include <asm/switch_to.h>
61#include <asm/tm.h>
61#include <asm/debug.h> 62#include <asm/debug.h>
62 63
63#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) 64#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
@@ -78,6 +79,13 @@ EXPORT_SYMBOL(__debugger_break_match);
78EXPORT_SYMBOL(__debugger_fault_handler); 79EXPORT_SYMBOL(__debugger_fault_handler);
79#endif 80#endif
80 81
82/* Transactional Memory trap debug */
83#ifdef TM_DEBUG_SW
84#define TM_DEBUG(x...) printk(KERN_INFO x)
85#else
86#define TM_DEBUG(x...) do { } while(0)
87#endif
88
81/* 89/*
82 * Trap & Exception support 90 * Trap & Exception support
83 */ 91 */
@@ -350,6 +358,7 @@ static inline int check_io_access(struct pt_regs *regs)
350 exception is in the MSR. */ 358 exception is in the MSR. */
351#define get_reason(regs) ((regs)->msr) 359#define get_reason(regs) ((regs)->msr)
352#define get_mc_reason(regs) ((regs)->msr) 360#define get_mc_reason(regs) ((regs)->msr)
361#define REASON_TM 0x200000
353#define REASON_FP 0x100000 362#define REASON_FP 0x100000
354#define REASON_ILLEGAL 0x80000 363#define REASON_ILLEGAL 0x80000
355#define REASON_PRIVILEGED 0x40000 364#define REASON_PRIVILEGED 0x40000
@@ -1020,6 +1029,38 @@ void __kprobes program_check_exception(struct pt_regs *regs)
1020 _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); 1029 _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
1021 return; 1030 return;
1022 } 1031 }
1032#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1033 if (reason & REASON_TM) {
1034 /* This is a TM "Bad Thing Exception" program check.
1035 * This occurs when:
1036 * - An rfid/hrfid/mtmsrd attempts to cause an illegal
1037 * transition in TM states.
1038 * - A trechkpt is attempted when transactional.
1039 * - A treclaim is attempted when non transactional.
1040 * - A tend is illegally attempted.
1041 * - writing a TM SPR when transactional.
1042 */
1043 if (!user_mode(regs) &&
1044 report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) {
1045 regs->nip += 4;
1046 return;
1047 }
1048 /* If usermode caused this, it's done something illegal and
1049 * gets a SIGILL slap on the wrist. We call it an illegal
1050 * operand to distinguish from the instruction just being bad
1051 * (e.g. executing a 'tend' on a CPU without TM!); it's an
1052 * illegal /placement/ of a valid instruction.
1053 */
1054 if (user_mode(regs)) {
1055 _exception(SIGILL, regs, ILL_ILLOPN, regs->nip);
1056 return;
1057 } else {
1058 printk(KERN_EMERG "Unexpected TM Bad Thing exception "
1059 "at %lx (msr 0x%x)\n", regs->nip, reason);
1060 die("Unrecoverable exception", regs, SIGABRT);
1061 }
1062 }
1063#endif
1023 1064
1024 /* We restore the interrupt state now */ 1065 /* We restore the interrupt state now */
1025 if (!arch_irq_disabled_regs(regs)) 1066 if (!arch_irq_disabled_regs(regs))
@@ -1160,6 +1201,109 @@ void vsx_unavailable_exception(struct pt_regs *regs)
1160 die("Unrecoverable VSX Unavailable Exception", regs, SIGABRT); 1201 die("Unrecoverable VSX Unavailable Exception", regs, SIGABRT);
1161} 1202}
1162 1203
1204void tm_unavailable_exception(struct pt_regs *regs)
1205{
1206 /* We restore the interrupt state now */
1207 if (!arch_irq_disabled_regs(regs))
1208 local_irq_enable();
1209
1210 /* Currently we never expect a TMU exception. Catch
1211 * this and kill the process!
1212 */
1213 printk(KERN_EMERG "Unexpected TM unavailable exception at %lx "
1214 "(msr %lx)\n",
1215 regs->nip, regs->msr);
1216
1217 if (user_mode(regs)) {
1218 _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
1219 return;
1220 }
1221
1222 die("Unexpected TM unavailable exception", regs, SIGABRT);
1223}
1224
1225#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1226
1227extern void do_load_up_fpu(struct pt_regs *regs);
1228
1229void fp_unavailable_tm(struct pt_regs *regs)
1230{
1231 /* Note: This does not handle any kind of FP laziness. */
1232
1233 TM_DEBUG("FP Unavailable trap whilst transactional at 0x%lx, MSR=%lx\n",
1234 regs->nip, regs->msr);
1235 tm_enable();
1236
1237 /* We can only have got here if the task started using FP after
1238 * beginning the transaction. So, the transactional regs are just a
1239 * copy of the checkpointed ones. But, we still need to recheckpoint
1240 * as we're enabling FP for the process; it will return, abort the
1241 * transaction, and probably retry but now with FP enabled. So the
1242 * checkpointed FP registers need to be loaded.
1243 */
1244 tm_reclaim(&current->thread, current->thread.regs->msr,
1245 TM_CAUSE_FAC_UNAV);
1246 /* Reclaim didn't save out any FPRs to transact_fprs. */
1247
1248 /* Enable FP for the task: */
1249 regs->msr |= (MSR_FP | current->thread.fpexc_mode);
1250
1251 /* This loads and recheckpoints the FP registers from
1252 * thread.fpr[]. They will remain in registers after the
1253 * checkpoint so we don't need to reload them after.
1254 */
1255 tm_recheckpoint(&current->thread, regs->msr);
1256}
1257
1258#ifdef CONFIG_ALTIVEC
1259extern void do_load_up_altivec(struct pt_regs *regs);
1260
1261void altivec_unavailable_tm(struct pt_regs *regs)
1262{
1263 /* See the comments in fp_unavailable_tm(). This function operates
1264 * the same way.
1265 */
1266
1267 TM_DEBUG("Vector Unavailable trap whilst transactional at 0x%lx,"
1268 "MSR=%lx\n",
1269 regs->nip, regs->msr);
1270 tm_enable();
1271 tm_reclaim(&current->thread, current->thread.regs->msr,
1272 TM_CAUSE_FAC_UNAV);
1273 regs->msr |= MSR_VEC;
1274 tm_recheckpoint(&current->thread, regs->msr);
1275 current->thread.used_vr = 1;
1276}
1277#endif
1278
1279#ifdef CONFIG_VSX
1280void vsx_unavailable_tm(struct pt_regs *regs)
1281{
1282 /* See the comments in fp_unavailable_tm(). This works similarly,
1283 * though we're loading both FP and VEC registers in here.
1284 *
1285 * If FP isn't in use, load FP regs. If VEC isn't in use, load VEC
1286 * regs. Either way, set MSR_VSX.
1287 */
1288
1289 TM_DEBUG("VSX Unavailable trap whilst transactional at 0x%lx,"
1290 "MSR=%lx\n",
1291 regs->nip, regs->msr);
1292
1293 tm_enable();
1294 /* This reclaims FP and/or VR regs if they're already enabled */
1295 tm_reclaim(&current->thread, current->thread.regs->msr,
1296 TM_CAUSE_FAC_UNAV);
1297
1298 regs->msr |= MSR_VEC | MSR_FP | current->thread.fpexc_mode |
1299 MSR_VSX;
1300 /* This loads & recheckpoints FP and VRs. */
1301 tm_recheckpoint(&current->thread, regs->msr);
1302 current->thread.used_vsr = 1;
1303}
1304#endif
1305#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
1306
1163void performance_monitor_exception(struct pt_regs *regs) 1307void performance_monitor_exception(struct pt_regs *regs)
1164{ 1308{
1165 __get_cpu_var(irq_stat).pmu_irqs++; 1309 __get_cpu_var(irq_stat).pmu_irqs++;
diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S
index e830289d2e48..9e20999aaef2 100644
--- a/arch/powerpc/kernel/vector.S
+++ b/arch/powerpc/kernel/vector.S
@@ -7,6 +7,57 @@
7#include <asm/page.h> 7#include <asm/page.h>
8#include <asm/ptrace.h> 8#include <asm/ptrace.h>
9 9
10#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
11/*
12 * Wrapper to call load_up_altivec from C.
13 * void do_load_up_altivec(struct pt_regs *regs);
14 */
15_GLOBAL(do_load_up_altivec)
16 mflr r0
17 std r0, 16(r1)
18 stdu r1, -112(r1)
19
20 subi r6, r3, STACK_FRAME_OVERHEAD
21 /* load_up_altivec expects r12=MSR, r13=PACA, and returns
22 * with r12 = new MSR.
23 */
24 ld r12,_MSR(r6)
25 GET_PACA(r13)
26 bl load_up_altivec
27 std r12,_MSR(r6)
28
29 ld r0, 112+16(r1)
30 addi r1, r1, 112
31 mtlr r0
32 blr
33
34/* void do_load_up_transact_altivec(struct thread_struct *thread)
35 *
36 * This is similar to load_up_altivec but for the transactional version of the
37 * vector regs. It doesn't mess with the task MSR or valid flags.
38 * Furthermore, VEC laziness is not supported with TM currently.
39 */
40_GLOBAL(do_load_up_transact_altivec)
41 mfmsr r6
42 oris r5,r6,MSR_VEC@h
43 MTMSRD(r5)
44 isync
45
46 li r4,1
47 stw r4,THREAD_USED_VR(r3)
48
49 li r10,THREAD_TRANSACT_VSCR
50 lvx vr0,r10,r3
51 mtvscr vr0
52 REST_32VRS_TRANSACT(0,r4,r3)
53
54 /* Disable VEC again. */
55 MTMSRD(r6)
56 isync
57
58 blr
59#endif
60
10/* 61/*
11 * load_up_altivec(unused, unused, tsk) 62 * load_up_altivec(unused, unused, tsk)
12 * Disable VMX for the task which had it previously, 63 * Disable VMX for the task which had it previously,
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 10b6c358dd77..e33d11f1b977 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -539,6 +539,11 @@ fast_guest_return:
539 539
540 /* Enter guest */ 540 /* Enter guest */
541 541
542BEGIN_FTR_SECTION
543 ld r5, VCPU_CFAR(r4)
544 mtspr SPRN_CFAR, r5
545END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
546
542 ld r5, VCPU_LR(r4) 547 ld r5, VCPU_LR(r4)
543 lwz r6, VCPU_CR(r4) 548 lwz r6, VCPU_CR(r4)
544 mtlr r5 549 mtlr r5
@@ -604,6 +609,10 @@ kvmppc_interrupt:
604 lwz r4, HSTATE_SCRATCH1(r13) 609 lwz r4, HSTATE_SCRATCH1(r13)
605 std r3, VCPU_GPR(R12)(r9) 610 std r3, VCPU_GPR(R12)(r9)
606 stw r4, VCPU_CR(r9) 611 stw r4, VCPU_CR(r9)
612BEGIN_FTR_SECTION
613 ld r3, HSTATE_CFAR(r13)
614 std r3, VCPU_CFAR(r9)
615END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
607 616
608 /* Restore R1/R2 so we can handle faults */ 617 /* Restore R1/R2 so we can handle faults */
609 ld r1, HSTATE_HOST_R1(r13) 618 ld r1, HSTATE_HOST_R1(r13)
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index 67e4708388a0..6702442ca818 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -35,6 +35,7 @@
35#include <asm/mmu_context.h> 35#include <asm/mmu_context.h>
36#include <asm/switch_to.h> 36#include <asm/switch_to.h>
37#include <asm/firmware.h> 37#include <asm/firmware.h>
38#include <asm/hvcall.h>
38#include <linux/gfp.h> 39#include <linux/gfp.h>
39#include <linux/sched.h> 40#include <linux/sched.h>
40#include <linux/vmalloc.h> 41#include <linux/vmalloc.h>
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 3a292be2e079..1b6e1271719f 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -55,6 +55,7 @@
55#include <asm/code-patching.h> 55#include <asm/code-patching.h>
56#include <asm/fadump.h> 56#include <asm/fadump.h>
57#include <asm/firmware.h> 57#include <asm/firmware.h>
58#include <asm/tm.h>
58 59
59#ifdef DEBUG 60#ifdef DEBUG
60#define DBG(fmt...) udbg_printf(fmt) 61#define DBG(fmt...) udbg_printf(fmt)
@@ -1171,6 +1172,21 @@ void flush_hash_page(unsigned long vpn, real_pte_t pte, int psize, int ssize,
1171 DBG_LOW(" sub %ld: hash=%lx, hidx=%lx\n", index, slot, hidx); 1172 DBG_LOW(" sub %ld: hash=%lx, hidx=%lx\n", index, slot, hidx);
1172 ppc_md.hpte_invalidate(slot, vpn, psize, ssize, local); 1173 ppc_md.hpte_invalidate(slot, vpn, psize, ssize, local);
1173 } pte_iterate_hashed_end(); 1174 } pte_iterate_hashed_end();
1175
1176#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1177 /* Transactions are not aborted by tlbiel, only tlbie.
1178 * Without, syncing a page back to a block device w/ PIO could pick up
1179 * transactional data (bad!) so we force an abort here. Before the
1180 * sync the page will be made read-only, which will flush_hash_page.
1181 * BIG ISSUE here: if the kernel uses a page from userspace without
1182 * unmapping it first, it may see the speculated version.
1183 */
1184 if (local && cpu_has_feature(CPU_FTR_TM) &&
1185 MSR_TM_ACTIVE(current->thread.regs->msr)) {
1186 tm_enable();
1187 tm_abort(TM_CAUSE_TLBI);
1188 }
1189#endif
1174} 1190}
1175 1191
1176void flush_hash_range(unsigned long number, int local) 1192void flush_hash_range(unsigned long number, int local)
diff --git a/arch/powerpc/platforms/ps3/htab.c b/arch/powerpc/platforms/ps3/htab.c
index d00d7b0a3bda..6cc58201db8c 100644
--- a/arch/powerpc/platforms/ps3/htab.c
+++ b/arch/powerpc/platforms/ps3/htab.c
@@ -27,6 +27,7 @@
27#include <asm/lv1call.h> 27#include <asm/lv1call.h>
28#include <asm/ps3fb.h> 28#include <asm/ps3fb.h>
29 29
30#define PS3_VERBOSE_RESULT
30#include "platform.h" 31#include "platform.h"
31 32
32/** 33/**
@@ -75,8 +76,9 @@ static long ps3_hpte_insert(unsigned long hpte_group, unsigned long vpn,
75 76
76 if (result) { 77 if (result) {
77 /* all entries bolted !*/ 78 /* all entries bolted !*/
78 pr_info("%s:result=%d vpn=%lx pa=%lx ix=%lx v=%llx r=%llx\n", 79 pr_info("%s:result=%s vpn=%lx pa=%lx ix=%lx v=%llx r=%llx\n",
79 __func__, result, vpn, pa, hpte_group, hpte_v, hpte_r); 80 __func__, ps3_result(result), vpn, pa, hpte_group,
81 hpte_v, hpte_r);
80 BUG(); 82 BUG();
81 } 83 }
82 84
@@ -125,8 +127,8 @@ static long ps3_hpte_updatepp(unsigned long slot, unsigned long newpp,
125 &hpte_rs); 127 &hpte_rs);
126 128
127 if (result) { 129 if (result) {
128 pr_info("%s: res=%d read vpn=%lx slot=%lx psize=%d\n", 130 pr_info("%s: result=%s read vpn=%lx slot=%lx psize=%d\n",
129 __func__, result, vpn, slot, psize); 131 __func__, ps3_result(result), vpn, slot, psize);
130 BUG(); 132 BUG();
131 } 133 }
132 134
@@ -170,8 +172,8 @@ static void ps3_hpte_invalidate(unsigned long slot, unsigned long vpn,
170 result = lv1_write_htab_entry(PS3_LPAR_VAS_ID_CURRENT, slot, 0, 0); 172 result = lv1_write_htab_entry(PS3_LPAR_VAS_ID_CURRENT, slot, 0, 0);
171 173
172 if (result) { 174 if (result) {
173 pr_info("%s: res=%d vpn=%lx slot=%lx psize=%d\n", 175 pr_info("%s: result=%s vpn=%lx slot=%lx psize=%d\n",
174 __func__, result, vpn, slot, psize); 176 __func__, ps3_result(result), vpn, slot, psize);
175 BUG(); 177 BUG();
176 } 178 }
177 179