aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-10-11 03:23:53 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-10-11 03:23:53 -0400
commit3ad26e5c4459d3793ad65bc8929037c70515df83 (patch)
tree434327df7942878383e372988eb5f3bccb25de12 /arch/powerpc
parent5293bf97a27e1be8ac6096aa198ff6a9e3e6837c (diff)
parent18461960cbf50bf345ef0667d45d5f64de8fb893 (diff)
Merge branch 'for-kvm' into next
Topic branch for commits that the KVM tree might want to pull in separately. Hand merged a few files due to conflicts with the LE stuff Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/include/asm/machdep.h12
-rw-r--r--arch/powerpc/include/asm/pgtable-ppc64.h2
-rw-r--r--arch/powerpc/include/asm/ppc_asm.h97
-rw-r--r--arch/powerpc/include/asm/processor.h47
-rw-r--r--arch/powerpc/include/asm/sfp-machine.h2
-rw-r--r--arch/powerpc/kernel/align.c8
-rw-r--r--arch/powerpc/kernel/asm-offsets.c27
-rw-r--r--arch/powerpc/kernel/fpu.S84
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c4
-rw-r--r--arch/powerpc/kernel/process.c15
-rw-r--r--arch/powerpc/kernel/ptrace.c49
-rw-r--r--arch/powerpc/kernel/ptrace32.c11
-rw-r--r--arch/powerpc/kernel/signal_32.c72
-rw-r--r--arch/powerpc/kernel/signal_64.c29
-rw-r--r--arch/powerpc/kernel/tm.S41
-rw-r--r--arch/powerpc/kernel/traps.c10
-rw-r--r--arch/powerpc/kernel/vecemu.c6
-rw-r--r--arch/powerpc/kernel/vector.S77
-rw-r--r--arch/powerpc/kvm/book3s_pr.c36
-rw-r--r--arch/powerpc/kvm/booke.c19
-rw-r--r--arch/powerpc/mm/init_64.c51
-rw-r--r--arch/powerpc/platforms/powernv/pci-ioda.c49
-rw-r--r--arch/powerpc/platforms/powernv/pci.c42
-rw-r--r--arch/powerpc/platforms/powernv/pci.h3
24 files changed, 410 insertions, 383 deletions
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index ce6cc2a7b8b9..ad3025d0880b 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -78,6 +78,18 @@ struct machdep_calls {
78 long index); 78 long index);
79 void (*tce_flush)(struct iommu_table *tbl); 79 void (*tce_flush)(struct iommu_table *tbl);
80 80
81 /* _rm versions are for real mode use only */
82 int (*tce_build_rm)(struct iommu_table *tbl,
83 long index,
84 long npages,
85 unsigned long uaddr,
86 enum dma_data_direction direction,
87 struct dma_attrs *attrs);
88 void (*tce_free_rm)(struct iommu_table *tbl,
89 long index,
90 long npages);
91 void (*tce_flush_rm)(struct iommu_table *tbl);
92
81 void __iomem * (*ioremap)(phys_addr_t addr, unsigned long size, 93 void __iomem * (*ioremap)(phys_addr_t addr, unsigned long size,
82 unsigned long flags, void *caller); 94 unsigned long flags, void *caller);
83 void (*iounmap)(volatile void __iomem *token); 95 void (*iounmap)(volatile void __iomem *token);
diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/include/asm/pgtable-ppc64.h
index 46db09414a10..4a191c472867 100644
--- a/arch/powerpc/include/asm/pgtable-ppc64.h
+++ b/arch/powerpc/include/asm/pgtable-ppc64.h
@@ -394,6 +394,8 @@ static inline void mark_hpte_slot_valid(unsigned char *hpte_slot_array,
394 hpte_slot_array[index] = hidx << 4 | 0x1 << 3; 394 hpte_slot_array[index] = hidx << 4 | 0x1 << 3;
395} 395}
396 396
397struct page *realmode_pfn_to_page(unsigned long pfn);
398
397static inline char *get_hpte_slot_array(pmd_t *pmdp) 399static inline char *get_hpte_slot_array(pmd_t *pmdp)
398{ 400{
399 /* 401 /*
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
index ce05bba0bfc6..8deaaad3b32f 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -98,88 +98,32 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR)
98#define REST_8GPRS(n, base) REST_4GPRS(n, base); REST_4GPRS(n+4, base) 98#define REST_8GPRS(n, base) REST_4GPRS(n, base); REST_4GPRS(n+4, base)
99#define REST_10GPRS(n, base) REST_8GPRS(n, base); REST_2GPRS(n+8, base) 99#define REST_10GPRS(n, base) REST_8GPRS(n, base); REST_2GPRS(n+8, base)
100 100
101#define SAVE_FPR(n, base) stfd n,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base) 101#define SAVE_FPR(n, base) stfd n,8*TS_FPRWIDTH*(n)(base)
102#define SAVE_2FPRS(n, base) SAVE_FPR(n, base); SAVE_FPR(n+1, base) 102#define SAVE_2FPRS(n, base) SAVE_FPR(n, base); SAVE_FPR(n+1, base)
103#define SAVE_4FPRS(n, base) SAVE_2FPRS(n, base); SAVE_2FPRS(n+2, base) 103#define SAVE_4FPRS(n, base) SAVE_2FPRS(n, base); SAVE_2FPRS(n+2, base)
104#define SAVE_8FPRS(n, base) SAVE_4FPRS(n, base); SAVE_4FPRS(n+4, base) 104#define SAVE_8FPRS(n, base) SAVE_4FPRS(n, base); SAVE_4FPRS(n+4, base)
105#define SAVE_16FPRS(n, base) SAVE_8FPRS(n, base); SAVE_8FPRS(n+8, base) 105#define SAVE_16FPRS(n, base) SAVE_8FPRS(n, base); SAVE_8FPRS(n+8, base)
106#define SAVE_32FPRS(n, base) SAVE_16FPRS(n, base); SAVE_16FPRS(n+16, base) 106#define SAVE_32FPRS(n, base) SAVE_16FPRS(n, base); SAVE_16FPRS(n+16, base)
107#define REST_FPR(n, base) lfd n,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base) 107#define REST_FPR(n, base) lfd n,8*TS_FPRWIDTH*(n)(base)
108#define REST_2FPRS(n, base) REST_FPR(n, base); REST_FPR(n+1, base) 108#define REST_2FPRS(n, base) REST_FPR(n, base); REST_FPR(n+1, base)
109#define REST_4FPRS(n, base) REST_2FPRS(n, base); REST_2FPRS(n+2, base) 109#define REST_4FPRS(n, base) REST_2FPRS(n, base); REST_2FPRS(n+2, base)
110#define REST_8FPRS(n, base) REST_4FPRS(n, base); REST_4FPRS(n+4, base) 110#define REST_8FPRS(n, base) REST_4FPRS(n, base); REST_4FPRS(n+4, base)
111#define REST_16FPRS(n, base) REST_8FPRS(n, base); REST_8FPRS(n+8, base) 111#define REST_16FPRS(n, base) REST_8FPRS(n, base); REST_8FPRS(n+8, base)
112#define REST_32FPRS(n, base) REST_16FPRS(n, base); REST_16FPRS(n+16, base) 112#define REST_32FPRS(n, base) REST_16FPRS(n, base); REST_16FPRS(n+16, base)
113 113
114#define SAVE_VR(n,b,base) li b,THREAD_VR0+(16*(n)); stvx n,base,b 114#define SAVE_VR(n,b,base) li b,16*(n); stvx n,base,b
115#define SAVE_2VRS(n,b,base) SAVE_VR(n,b,base); SAVE_VR(n+1,b,base) 115#define SAVE_2VRS(n,b,base) SAVE_VR(n,b,base); SAVE_VR(n+1,b,base)
116#define SAVE_4VRS(n,b,base) SAVE_2VRS(n,b,base); SAVE_2VRS(n+2,b,base) 116#define SAVE_4VRS(n,b,base) SAVE_2VRS(n,b,base); SAVE_2VRS(n+2,b,base)
117#define SAVE_8VRS(n,b,base) SAVE_4VRS(n,b,base); SAVE_4VRS(n+4,b,base) 117#define SAVE_8VRS(n,b,base) SAVE_4VRS(n,b,base); SAVE_4VRS(n+4,b,base)
118#define SAVE_16VRS(n,b,base) SAVE_8VRS(n,b,base); SAVE_8VRS(n+8,b,base) 118#define SAVE_16VRS(n,b,base) SAVE_8VRS(n,b,base); SAVE_8VRS(n+8,b,base)
119#define SAVE_32VRS(n,b,base) SAVE_16VRS(n,b,base); SAVE_16VRS(n+16,b,base) 119#define SAVE_32VRS(n,b,base) SAVE_16VRS(n,b,base); SAVE_16VRS(n+16,b,base)
120#define REST_VR(n,b,base) li b,THREAD_VR0+(16*(n)); lvx n,base,b 120#define REST_VR(n,b,base) li b,16*(n); lvx n,base,b
121#define REST_2VRS(n,b,base) REST_VR(n,b,base); REST_VR(n+1,b,base) 121#define REST_2VRS(n,b,base) REST_VR(n,b,base); REST_VR(n+1,b,base)
122#define REST_4VRS(n,b,base) REST_2VRS(n,b,base); REST_2VRS(n+2,b,base) 122#define REST_4VRS(n,b,base) REST_2VRS(n,b,base); REST_2VRS(n+2,b,base)
123#define REST_8VRS(n,b,base) REST_4VRS(n,b,base); REST_4VRS(n+4,b,base) 123#define REST_8VRS(n,b,base) REST_4VRS(n,b,base); REST_4VRS(n+4,b,base)
124#define REST_16VRS(n,b,base) REST_8VRS(n,b,base); REST_8VRS(n+8,b,base) 124#define REST_16VRS(n,b,base) REST_8VRS(n,b,base); REST_8VRS(n+8,b,base)
125#define REST_32VRS(n,b,base) REST_16VRS(n,b,base); REST_16VRS(n+16,b,base) 125#define REST_32VRS(n,b,base) REST_16VRS(n,b,base); REST_16VRS(n+16,b,base)
126 126
127/* Save/restore FPRs, VRs and VSRs from their checkpointed backups in
128 * thread_struct:
129 */
130#define SAVE_FPR_TRANSACT(n, base) stfd n,THREAD_TRANSACT_FPR0+ \
131 8*TS_FPRWIDTH*(n)(base)
132#define SAVE_2FPRS_TRANSACT(n, base) SAVE_FPR_TRANSACT(n, base); \
133 SAVE_FPR_TRANSACT(n+1, base)
134#define SAVE_4FPRS_TRANSACT(n, base) SAVE_2FPRS_TRANSACT(n, base); \
135 SAVE_2FPRS_TRANSACT(n+2, base)
136#define SAVE_8FPRS_TRANSACT(n, base) SAVE_4FPRS_TRANSACT(n, base); \
137 SAVE_4FPRS_TRANSACT(n+4, base)
138#define SAVE_16FPRS_TRANSACT(n, base) SAVE_8FPRS_TRANSACT(n, base); \
139 SAVE_8FPRS_TRANSACT(n+8, base)
140#define SAVE_32FPRS_TRANSACT(n, base) SAVE_16FPRS_TRANSACT(n, base); \
141 SAVE_16FPRS_TRANSACT(n+16, base)
142
143#define REST_FPR_TRANSACT(n, base) lfd n,THREAD_TRANSACT_FPR0+ \
144 8*TS_FPRWIDTH*(n)(base)
145#define REST_2FPRS_TRANSACT(n, base) REST_FPR_TRANSACT(n, base); \
146 REST_FPR_TRANSACT(n+1, base)
147#define REST_4FPRS_TRANSACT(n, base) REST_2FPRS_TRANSACT(n, base); \
148 REST_2FPRS_TRANSACT(n+2, base)
149#define REST_8FPRS_TRANSACT(n, base) REST_4FPRS_TRANSACT(n, base); \
150 REST_4FPRS_TRANSACT(n+4, base)
151#define REST_16FPRS_TRANSACT(n, base) REST_8FPRS_TRANSACT(n, base); \
152 REST_8FPRS_TRANSACT(n+8, base)
153#define REST_32FPRS_TRANSACT(n, base) REST_16FPRS_TRANSACT(n, base); \
154 REST_16FPRS_TRANSACT(n+16, base)
155
156
157#define SAVE_VR_TRANSACT(n,b,base) li b,THREAD_TRANSACT_VR0+(16*(n)); \
158 stvx n,b,base
159#define SAVE_2VRS_TRANSACT(n,b,base) SAVE_VR_TRANSACT(n,b,base); \
160 SAVE_VR_TRANSACT(n+1,b,base)
161#define SAVE_4VRS_TRANSACT(n,b,base) SAVE_2VRS_TRANSACT(n,b,base); \
162 SAVE_2VRS_TRANSACT(n+2,b,base)
163#define SAVE_8VRS_TRANSACT(n,b,base) SAVE_4VRS_TRANSACT(n,b,base); \
164 SAVE_4VRS_TRANSACT(n+4,b,base)
165#define SAVE_16VRS_TRANSACT(n,b,base) SAVE_8VRS_TRANSACT(n,b,base); \
166 SAVE_8VRS_TRANSACT(n+8,b,base)
167#define SAVE_32VRS_TRANSACT(n,b,base) SAVE_16VRS_TRANSACT(n,b,base); \
168 SAVE_16VRS_TRANSACT(n+16,b,base)
169
170#define REST_VR_TRANSACT(n,b,base) li b,THREAD_TRANSACT_VR0+(16*(n)); \
171 lvx n,b,base
172#define REST_2VRS_TRANSACT(n,b,base) REST_VR_TRANSACT(n,b,base); \
173 REST_VR_TRANSACT(n+1,b,base)
174#define REST_4VRS_TRANSACT(n,b,base) REST_2VRS_TRANSACT(n,b,base); \
175 REST_2VRS_TRANSACT(n+2,b,base)
176#define REST_8VRS_TRANSACT(n,b,base) REST_4VRS_TRANSACT(n,b,base); \
177 REST_4VRS_TRANSACT(n+4,b,base)
178#define REST_16VRS_TRANSACT(n,b,base) REST_8VRS_TRANSACT(n,b,base); \
179 REST_8VRS_TRANSACT(n+8,b,base)
180#define REST_32VRS_TRANSACT(n,b,base) REST_16VRS_TRANSACT(n,b,base); \
181 REST_16VRS_TRANSACT(n+16,b,base)
182
183#ifdef __BIG_ENDIAN__ 127#ifdef __BIG_ENDIAN__
184#define STXVD2X_ROT(n,b,base) STXVD2X(n,b,base) 128#define STXVD2X_ROT(n,b,base) STXVD2X(n,b,base)
185#define LXVD2X_ROT(n,b,base) LXVD2X(n,b,base) 129#define LXVD2X_ROT(n,b,base) LXVD2X(n,b,base)
@@ -191,43 +135,14 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR)
191#define LXVD2X_ROT(n,b,base) LXVD2X(n,b,base); \ 135#define LXVD2X_ROT(n,b,base) LXVD2X(n,b,base); \
192 XXSWAPD(n,n) 136 XXSWAPD(n,n)
193#endif 137#endif
194
195#define SAVE_VSR_TRANSACT(n,b,base) li b,THREAD_TRANSACT_VSR0+(16*(n)); \
196 STXVD2X_ROT(n,R##base,R##b)
197#define SAVE_2VSRS_TRANSACT(n,b,base) SAVE_VSR_TRANSACT(n,b,base); \
198 SAVE_VSR_TRANSACT(n+1,b,base)
199#define SAVE_4VSRS_TRANSACT(n,b,base) SAVE_2VSRS_TRANSACT(n,b,base); \
200 SAVE_2VSRS_TRANSACT(n+2,b,base)
201#define SAVE_8VSRS_TRANSACT(n,b,base) SAVE_4VSRS_TRANSACT(n,b,base); \
202 SAVE_4VSRS_TRANSACT(n+4,b,base)
203#define SAVE_16VSRS_TRANSACT(n,b,base) SAVE_8VSRS_TRANSACT(n,b,base); \
204 SAVE_8VSRS_TRANSACT(n+8,b,base)
205#define SAVE_32VSRS_TRANSACT(n,b,base) SAVE_16VSRS_TRANSACT(n,b,base); \
206 SAVE_16VSRS_TRANSACT(n+16,b,base)
207
208#define REST_VSR_TRANSACT(n,b,base) li b,THREAD_TRANSACT_VSR0+(16*(n)); \
209 LXVD2X_ROT(n,R##base,R##b)
210#define REST_2VSRS_TRANSACT(n,b,base) REST_VSR_TRANSACT(n,b,base); \
211 REST_VSR_TRANSACT(n+1,b,base)
212#define REST_4VSRS_TRANSACT(n,b,base) REST_2VSRS_TRANSACT(n,b,base); \
213 REST_2VSRS_TRANSACT(n+2,b,base)
214#define REST_8VSRS_TRANSACT(n,b,base) REST_4VSRS_TRANSACT(n,b,base); \
215 REST_4VSRS_TRANSACT(n+4,b,base)
216#define REST_16VSRS_TRANSACT(n,b,base) REST_8VSRS_TRANSACT(n,b,base); \
217 REST_8VSRS_TRANSACT(n+8,b,base)
218#define REST_32VSRS_TRANSACT(n,b,base) REST_16VSRS_TRANSACT(n,b,base); \
219 REST_16VSRS_TRANSACT(n+16,b,base)
220
221/* Save the lower 32 VSRs in the thread VSR region */ 138/* Save the lower 32 VSRs in the thread VSR region */
222#define SAVE_VSR(n,b,base) li b,THREAD_VSR0+(16*(n)); \ 139#define SAVE_VSR(n,b,base) li b,16*(n); STXVD2X_ROT(n,R##base,R##b)
223 STXVD2X_ROT(n,R##base,R##b)
224#define SAVE_2VSRS(n,b,base) SAVE_VSR(n,b,base); SAVE_VSR(n+1,b,base) 140#define SAVE_2VSRS(n,b,base) SAVE_VSR(n,b,base); SAVE_VSR(n+1,b,base)
225#define SAVE_4VSRS(n,b,base) SAVE_2VSRS(n,b,base); SAVE_2VSRS(n+2,b,base) 141#define SAVE_4VSRS(n,b,base) SAVE_2VSRS(n,b,base); SAVE_2VSRS(n+2,b,base)
226#define SAVE_8VSRS(n,b,base) SAVE_4VSRS(n,b,base); SAVE_4VSRS(n+4,b,base) 142#define SAVE_8VSRS(n,b,base) SAVE_4VSRS(n,b,base); SAVE_4VSRS(n+4,b,base)
227#define SAVE_16VSRS(n,b,base) SAVE_8VSRS(n,b,base); SAVE_8VSRS(n+8,b,base) 143#define SAVE_16VSRS(n,b,base) SAVE_8VSRS(n,b,base); SAVE_8VSRS(n+8,b,base)
228#define SAVE_32VSRS(n,b,base) SAVE_16VSRS(n,b,base); SAVE_16VSRS(n+16,b,base) 144#define SAVE_32VSRS(n,b,base) SAVE_16VSRS(n,b,base); SAVE_16VSRS(n+16,b,base)
229#define REST_VSR(n,b,base) li b,THREAD_VSR0+(16*(n)); \ 145#define REST_VSR(n,b,base) li b,16*(n); LXVD2X_ROT(n,R##base,R##b)
230 LXVD2X_ROT(n,R##base,R##b)
231#define REST_2VSRS(n,b,base) REST_VSR(n,b,base); REST_VSR(n+1,b,base) 146#define REST_2VSRS(n,b,base) REST_VSR(n,b,base); REST_VSR(n+1,b,base)
232#define REST_4VSRS(n,b,base) REST_2VSRS(n,b,base); REST_2VSRS(n+2,b,base) 147#define REST_4VSRS(n,b,base) REST_2VSRS(n,b,base); REST_2VSRS(n+2,b,base)
233#define REST_8VSRS(n,b,base) REST_4VSRS(n,b,base); REST_4VSRS(n+4,b,base) 148#define REST_8VSRS(n,b,base) REST_4VSRS(n,b,base); REST_4VSRS(n+4,b,base)
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 82c6ee9df9a1..c1583070937d 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -152,8 +152,20 @@ typedef struct {
152 unsigned long seg; 152 unsigned long seg;
153} mm_segment_t; 153} mm_segment_t;
154 154
155#define TS_FPR(i) fpr[i][TS_FPROFFSET] 155#define TS_FPR(i) fp_state.fpr[i][TS_FPROFFSET]
156#define TS_TRANS_FPR(i) transact_fpr[i][TS_FPROFFSET] 156#define TS_TRANS_FPR(i) transact_fp.fpr[i][TS_FPROFFSET]
157
158/* FP and VSX 0-31 register set */
159struct thread_fp_state {
160 u64 fpr[32][TS_FPRWIDTH] __attribute__((aligned(16)));
161 u64 fpscr; /* Floating point status */
162};
163
164/* Complete AltiVec register set including VSCR */
165struct thread_vr_state {
166 vector128 vr[32] __attribute__((aligned(16)));
167 vector128 vscr __attribute__((aligned(16)));
168};
157 169
158struct thread_struct { 170struct thread_struct {
159 unsigned long ksp; /* Kernel stack pointer */ 171 unsigned long ksp; /* Kernel stack pointer */
@@ -206,13 +218,8 @@ struct thread_struct {
206 unsigned long dvc2; 218 unsigned long dvc2;
207#endif 219#endif
208#endif 220#endif
209 /* FP and VSX 0-31 register set */ 221 struct thread_fp_state fp_state;
210 double fpr[32][TS_FPRWIDTH] __attribute__((aligned(16))); 222 struct thread_fp_state *fp_save_area;
211 struct {
212
213 unsigned int pad;
214 unsigned int val; /* Floating point status */
215 } fpscr;
216 int fpexc_mode; /* floating-point exception mode */ 223 int fpexc_mode; /* floating-point exception mode */
217 unsigned int align_ctl; /* alignment handling control */ 224 unsigned int align_ctl; /* alignment handling control */
218#ifdef CONFIG_PPC64 225#ifdef CONFIG_PPC64
@@ -230,10 +237,8 @@ struct thread_struct {
230 struct arch_hw_breakpoint hw_brk; /* info on the hardware breakpoint */ 237 struct arch_hw_breakpoint hw_brk; /* info on the hardware breakpoint */
231 unsigned long trap_nr; /* last trap # on this thread */ 238 unsigned long trap_nr; /* last trap # on this thread */
232#ifdef CONFIG_ALTIVEC 239#ifdef CONFIG_ALTIVEC
233 /* Complete AltiVec register set */ 240 struct thread_vr_state vr_state;
234 vector128 vr[32] __attribute__((aligned(16))); 241 struct thread_vr_state *vr_save_area;
235 /* AltiVec status */
236 vector128 vscr __attribute__((aligned(16)));
237 unsigned long vrsave; 242 unsigned long vrsave;
238 int used_vr; /* set if process has used altivec */ 243 int used_vr; /* set if process has used altivec */
239#endif /* CONFIG_ALTIVEC */ 244#endif /* CONFIG_ALTIVEC */
@@ -270,13 +275,8 @@ struct thread_struct {
270 * transact_fpr[] is the new set of transactional values. 275 * transact_fpr[] is the new set of transactional values.
271 * VRs work the same way. 276 * VRs work the same way.
272 */ 277 */
273 double transact_fpr[32][TS_FPRWIDTH]; 278 struct thread_fp_state transact_fp;
274 struct { 279 struct thread_vr_state transact_vr;
275 unsigned int pad;
276 unsigned int val; /* Floating point status */
277 } transact_fpscr;
278 vector128 transact_vr[32] __attribute__((aligned(16)));
279 vector128 transact_vscr __attribute__((aligned(16)));
280 unsigned long transact_vrsave; 280 unsigned long transact_vrsave;
281#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ 281#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
282#ifdef CONFIG_KVM_BOOK3S_32_HANDLER 282#ifdef CONFIG_KVM_BOOK3S_32_HANDLER
@@ -330,8 +330,6 @@ struct thread_struct {
330 .ksp = INIT_SP, \ 330 .ksp = INIT_SP, \
331 .regs = (struct pt_regs *)INIT_SP - 1, /* XXX bogus, I think */ \ 331 .regs = (struct pt_regs *)INIT_SP - 1, /* XXX bogus, I think */ \
332 .fs = KERNEL_DS, \ 332 .fs = KERNEL_DS, \
333 .fpr = {{0}}, \
334 .fpscr = { .val = 0, }, \
335 .fpexc_mode = 0, \ 333 .fpexc_mode = 0, \
336 .ppr = INIT_PPR, \ 334 .ppr = INIT_PPR, \
337} 335}
@@ -369,6 +367,11 @@ extern int set_endian(struct task_struct *tsk, unsigned int val);
369extern int get_unalign_ctl(struct task_struct *tsk, unsigned long adr); 367extern int get_unalign_ctl(struct task_struct *tsk, unsigned long adr);
370extern int set_unalign_ctl(struct task_struct *tsk, unsigned int val); 368extern int set_unalign_ctl(struct task_struct *tsk, unsigned int val);
371 369
370extern void load_fp_state(struct thread_fp_state *fp);
371extern void store_fp_state(struct thread_fp_state *fp);
372extern void load_vr_state(struct thread_vr_state *vr);
373extern void store_vr_state(struct thread_vr_state *vr);
374
372static inline unsigned int __unpack_fe01(unsigned long msr_bits) 375static inline unsigned int __unpack_fe01(unsigned long msr_bits)
373{ 376{
374 return ((msr_bits & MSR_FE0) >> 10) | ((msr_bits & MSR_FE1) >> 8); 377 return ((msr_bits & MSR_FE0) >> 10) | ((msr_bits & MSR_FE1) >> 8);
diff --git a/arch/powerpc/include/asm/sfp-machine.h b/arch/powerpc/include/asm/sfp-machine.h
index 3a7a67a0d006..d89beaba26ff 100644
--- a/arch/powerpc/include/asm/sfp-machine.h
+++ b/arch/powerpc/include/asm/sfp-machine.h
@@ -125,7 +125,7 @@
125#define FP_EX_DIVZERO (1 << (31 - 5)) 125#define FP_EX_DIVZERO (1 << (31 - 5))
126#define FP_EX_INEXACT (1 << (31 - 6)) 126#define FP_EX_INEXACT (1 << (31 - 6))
127 127
128#define __FPU_FPSCR (current->thread.fpscr.val) 128#define __FPU_FPSCR (current->thread.fp_state.fpscr)
129 129
130/* We only actually write to the destination register 130/* We only actually write to the destination register
131 * if exceptions signalled (if any) will not trap. 131 * if exceptions signalled (if any) will not trap.
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
index 59f70adcbcd9..6e3f9772aaba 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -652,9 +652,9 @@ static int emulate_vsx(unsigned char __user *addr, unsigned int reg,
652 flush_vsx_to_thread(current); 652 flush_vsx_to_thread(current);
653 653
654 if (reg < 32) 654 if (reg < 32)
655 ptr = (char *) &current->thread.fpr[reg][0]; 655 ptr = (char *) &current->thread.fp_state.fpr[reg][0];
656 else 656 else
657 ptr = (char *) &current->thread.vr[reg - 32]; 657 ptr = (char *) &current->thread.vr_state.vr[reg - 32];
658 658
659 lptr = (unsigned long *) ptr; 659 lptr = (unsigned long *) ptr;
660 660
@@ -944,7 +944,7 @@ int fix_alignment(struct pt_regs *regs)
944 return -EFAULT; 944 return -EFAULT;
945 945
946 } else if (flags & F) { 946 } else if (flags & F) {
947 data.dd = current->thread.TS_FPR(reg); 947 data.ll = current->thread.TS_FPR(reg);
948 if (flags & S) { 948 if (flags & S) {
949 /* Single-precision FP store requires conversion... */ 949 /* Single-precision FP store requires conversion... */
950#ifdef CONFIG_PPC_FPU 950#ifdef CONFIG_PPC_FPU
@@ -1021,7 +1021,7 @@ int fix_alignment(struct pt_regs *regs)
1021 if (unlikely(ret)) 1021 if (unlikely(ret))
1022 return -EFAULT; 1022 return -EFAULT;
1023 } else if (flags & F) 1023 } else if (flags & F)
1024 current->thread.TS_FPR(reg) = data.dd; 1024 current->thread.TS_FPR(reg) = data.ll;
1025 else 1025 else
1026 regs->gpr[reg] = data.ll; 1026 regs->gpr[reg] = data.ll;
1027 1027
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 502c7a4e73f7..6278edddc3f8 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -90,16 +90,17 @@ int main(void)
90 DEFINE(THREAD_NORMSAVES, offsetof(struct thread_struct, normsave[0])); 90 DEFINE(THREAD_NORMSAVES, offsetof(struct thread_struct, normsave[0]));
91#endif 91#endif
92 DEFINE(THREAD_FPEXC_MODE, offsetof(struct thread_struct, fpexc_mode)); 92 DEFINE(THREAD_FPEXC_MODE, offsetof(struct thread_struct, fpexc_mode));
93 DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0])); 93 DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fp_state));
94 DEFINE(THREAD_FPSCR, offsetof(struct thread_struct, fpscr)); 94 DEFINE(THREAD_FPSAVEAREA, offsetof(struct thread_struct, fp_save_area));
95 DEFINE(FPSTATE_FPSCR, offsetof(struct thread_fp_state, fpscr));
95#ifdef CONFIG_ALTIVEC 96#ifdef CONFIG_ALTIVEC
96 DEFINE(THREAD_VR0, offsetof(struct thread_struct, vr[0])); 97 DEFINE(THREAD_VRSTATE, offsetof(struct thread_struct, vr_state));
98 DEFINE(THREAD_VRSAVEAREA, offsetof(struct thread_struct, vr_save_area));
97 DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave)); 99 DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave));
98 DEFINE(THREAD_VSCR, offsetof(struct thread_struct, vscr));
99 DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr)); 100 DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr));
101 DEFINE(VRSTATE_VSCR, offsetof(struct thread_vr_state, vscr));
100#endif /* CONFIG_ALTIVEC */ 102#endif /* CONFIG_ALTIVEC */
101#ifdef CONFIG_VSX 103#ifdef CONFIG_VSX
102 DEFINE(THREAD_VSR0, offsetof(struct thread_struct, fpr));
103 DEFINE(THREAD_USED_VSR, offsetof(struct thread_struct, used_vsr)); 104 DEFINE(THREAD_USED_VSR, offsetof(struct thread_struct, used_vsr));
104#endif /* CONFIG_VSX */ 105#endif /* CONFIG_VSX */
105#ifdef CONFIG_PPC64 106#ifdef CONFIG_PPC64
@@ -143,20 +144,12 @@ int main(void)
143 DEFINE(THREAD_TM_PPR, offsetof(struct thread_struct, tm_ppr)); 144 DEFINE(THREAD_TM_PPR, offsetof(struct thread_struct, tm_ppr));
144 DEFINE(THREAD_TM_DSCR, offsetof(struct thread_struct, tm_dscr)); 145 DEFINE(THREAD_TM_DSCR, offsetof(struct thread_struct, tm_dscr));
145 DEFINE(PT_CKPT_REGS, offsetof(struct thread_struct, ckpt_regs)); 146 DEFINE(PT_CKPT_REGS, offsetof(struct thread_struct, ckpt_regs));
146 DEFINE(THREAD_TRANSACT_VR0, offsetof(struct thread_struct, 147 DEFINE(THREAD_TRANSACT_VRSTATE, offsetof(struct thread_struct,
147 transact_vr[0])); 148 transact_vr));
148 DEFINE(THREAD_TRANSACT_VSCR, offsetof(struct thread_struct,
149 transact_vscr));
150 DEFINE(THREAD_TRANSACT_VRSAVE, offsetof(struct thread_struct, 149 DEFINE(THREAD_TRANSACT_VRSAVE, offsetof(struct thread_struct,
151 transact_vrsave)); 150 transact_vrsave));
152 DEFINE(THREAD_TRANSACT_FPR0, offsetof(struct thread_struct, 151 DEFINE(THREAD_TRANSACT_FPSTATE, offsetof(struct thread_struct,
153 transact_fpr[0])); 152 transact_fp));
154 DEFINE(THREAD_TRANSACT_FPSCR, offsetof(struct thread_struct,
155 transact_fpscr));
156#ifdef CONFIG_VSX
157 DEFINE(THREAD_TRANSACT_VSR0, offsetof(struct thread_struct,
158 transact_fpr[0]));
159#endif
160 /* Local pt_regs on stack for Transactional Memory funcs. */ 153 /* Local pt_regs on stack for Transactional Memory funcs. */
161 DEFINE(TM_FRAME_SIZE, STACK_FRAME_OVERHEAD + 154 DEFINE(TM_FRAME_SIZE, STACK_FRAME_OVERHEAD +
162 sizeof(struct pt_regs) + 16); 155 sizeof(struct pt_regs) + 16);
diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S
index caeaabf11a2f..4dca05e91e95 100644
--- a/arch/powerpc/kernel/fpu.S
+++ b/arch/powerpc/kernel/fpu.S
@@ -35,15 +35,6 @@ 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
47#define __SAVE_32FPVSRS(n,c,base) \ 38#define __SAVE_32FPVSRS(n,c,base) \
48BEGIN_FTR_SECTION \ 39BEGIN_FTR_SECTION \
49 b 2f; \ 40 b 2f; \
@@ -54,40 +45,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX); \
543: 453:
55#else 46#else
56#define __REST_32FPVSRS(n,b,base) REST_32FPRS(n, base) 47#define __REST_32FPVSRS(n,b,base) REST_32FPRS(n, base)
57#define __REST_32FPVSRS_TRANSACT(n,b,base) REST_32FPRS(n, base)
58#define __SAVE_32FPVSRS(n,b,base) SAVE_32FPRS(n, base) 48#define __SAVE_32FPVSRS(n,b,base) SAVE_32FPRS(n, base)
59#endif 49#endif
60#define REST_32FPVSRS(n,c,base) __REST_32FPVSRS(n,__REG_##c,__REG_##base) 50#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)
63#define SAVE_32FPVSRS(n,c,base) __SAVE_32FPVSRS(n,__REG_##c,__REG_##base) 51#define SAVE_32FPVSRS(n,c,base) __SAVE_32FPVSRS(n,__REG_##c,__REG_##base)
64 52
65#ifdef CONFIG_PPC_TRANSACTIONAL_MEM 53#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) 54/* void do_load_up_transact_fpu(struct thread_struct *thread)
92 * 55 *
93 * This is similar to load_up_fpu but for the transactional version of the FP 56 * This is similar to load_up_fpu but for the transactional version of the FP
@@ -105,9 +68,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
105 SYNC 68 SYNC
106 MTMSRD(r5) 69 MTMSRD(r5)
107 70
108 lfd fr0,THREAD_TRANSACT_FPSCR(r3) 71 addi r7,r3,THREAD_TRANSACT_FPSTATE
72 lfd fr0,FPSTATE_FPSCR(r7)
109 MTFSF_L(fr0) 73 MTFSF_L(fr0)
110 REST_32FPVSRS_TRANSACT(0, R4, R3) 74 REST_32FPVSRS(0, R4, R7)
111 75
112 /* FP/VSX off again */ 76 /* FP/VSX off again */
113 MTMSRD(r6) 77 MTMSRD(r6)
@@ -117,6 +81,26 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
117#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ 81#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
118 82
119/* 83/*
84 * Load state from memory into FP registers including FPSCR.
85 * Assumes the caller has enabled FP in the MSR.
86 */
87_GLOBAL(load_fp_state)
88 lfd fr0,FPSTATE_FPSCR(r3)
89 MTFSF_L(fr0)
90 REST_32FPVSRS(0, R4, R3)
91 blr
92
93/*
94 * Store FP state into memory, including FPSCR
95 * Assumes the caller has enabled FP in the MSR.
96 */
97_GLOBAL(store_fp_state)
98 SAVE_32FPVSRS(0, R4, R3)
99 mffs fr0
100 stfd fr0,FPSTATE_FPSCR(r3)
101 blr
102
103/*
120 * This task wants to use the FPU now. 104 * This task wants to use the FPU now.
121 * On UP, disable FP for the task which had the FPU previously, 105 * On UP, disable FP for the task which had the FPU previously,
122 * and save its floating-point registers in its thread_struct. 106 * and save its floating-point registers in its thread_struct.
@@ -147,9 +131,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
147 beq 1f 131 beq 1f
148 toreal(r4) 132 toreal(r4)
149 addi r4,r4,THREAD /* want last_task_used_math->thread */ 133 addi r4,r4,THREAD /* want last_task_used_math->thread */
150 SAVE_32FPVSRS(0, R5, R4) 134 addi r8,r4,THREAD_FPSTATE
135 SAVE_32FPVSRS(0, R5, R8)
151 mffs fr0 136 mffs fr0
152 stfd fr0,THREAD_FPSCR(r4) 137 stfd fr0,FPSTATE_FPSCR(r8)
153 PPC_LL r5,PT_REGS(r4) 138 PPC_LL r5,PT_REGS(r4)
154 toreal(r5) 139 toreal(r5)
155 PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5) 140 PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
@@ -160,7 +145,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
160#endif /* CONFIG_SMP */ 145#endif /* CONFIG_SMP */
161 /* enable use of FP after return */ 146 /* enable use of FP after return */
162#ifdef CONFIG_PPC32 147#ifdef CONFIG_PPC32
163 mfspr r5,SPRN_SPRG_THREAD /* current task's THREAD (phys) */ 148 mfspr r5,SPRN_SPRG_THREAD /* current task's THREAD (phys) */
164 lwz r4,THREAD_FPEXC_MODE(r5) 149 lwz r4,THREAD_FPEXC_MODE(r5)
165 ori r9,r9,MSR_FP /* enable FP for current */ 150 ori r9,r9,MSR_FP /* enable FP for current */
166 or r9,r9,r4 151 or r9,r9,r4
@@ -172,9 +157,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
172 or r12,r12,r4 157 or r12,r12,r4
173 std r12,_MSR(r1) 158 std r12,_MSR(r1)
174#endif 159#endif
175 lfd fr0,THREAD_FPSCR(r5) 160 addi r7,r5,THREAD_FPSTATE
161 lfd fr0,FPSTATE_FPSCR(r7)
176 MTFSF_L(fr0) 162 MTFSF_L(fr0)
177 REST_32FPVSRS(0, R4, R5) 163 REST_32FPVSRS(0, R4, R7)
178#ifndef CONFIG_SMP 164#ifndef CONFIG_SMP
179 subi r4,r5,THREAD 165 subi r4,r5,THREAD
180 fromreal(r4) 166 fromreal(r4)
@@ -206,11 +192,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
206 PPC_LCMPI 0,r3,0 192 PPC_LCMPI 0,r3,0
207 beqlr- /* if no previous owner, done */ 193 beqlr- /* if no previous owner, done */
208 addi r3,r3,THREAD /* want THREAD of task */ 194 addi r3,r3,THREAD /* want THREAD of task */
195 PPC_LL r6,THREAD_FPSAVEAREA(r3)
209 PPC_LL r5,PT_REGS(r3) 196 PPC_LL r5,PT_REGS(r3)
210 PPC_LCMPI 0,r5,0 197 PPC_LCMPI 0,r6,0
211 SAVE_32FPVSRS(0, R4 ,R3) 198 bne 2f
199 addi r6,r3,THREAD_FPSTATE
2002: PPC_LCMPI 0,r5,0
201 SAVE_32FPVSRS(0, R4, R6)
212 mffs fr0 202 mffs fr0
213 stfd fr0,THREAD_FPSCR(r3) 203 stfd fr0,FPSTATE_FPSCR(r6)
214 beq 1f 204 beq 1f
215 PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5) 205 PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
216 li r3,MSR_FP|MSR_FE0|MSR_FE1 206 li r3,MSR_FP|MSR_FE0|MSR_FE1
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index d8c34073b42a..3bd77edd7610 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -100,9 +100,13 @@ EXPORT_SYMBOL(start_thread);
100 100
101#ifdef CONFIG_PPC_FPU 101#ifdef CONFIG_PPC_FPU
102EXPORT_SYMBOL(giveup_fpu); 102EXPORT_SYMBOL(giveup_fpu);
103EXPORT_SYMBOL(load_fp_state);
104EXPORT_SYMBOL(store_fp_state);
103#endif 105#endif
104#ifdef CONFIG_ALTIVEC 106#ifdef CONFIG_ALTIVEC
105EXPORT_SYMBOL(giveup_altivec); 107EXPORT_SYMBOL(giveup_altivec);
108EXPORT_SYMBOL(load_vr_state);
109EXPORT_SYMBOL(store_vr_state);
106#endif /* CONFIG_ALTIVEC */ 110#endif /* CONFIG_ALTIVEC */
107#ifdef CONFIG_VSX 111#ifdef CONFIG_VSX
108EXPORT_SYMBOL(giveup_vsx); 112EXPORT_SYMBOL(giveup_vsx);
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 96d2fdf3aa9e..8649a3d629e1 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1008,6 +1008,11 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
1008 p->thread.ptrace_bps[0] = NULL; 1008 p->thread.ptrace_bps[0] = NULL;
1009#endif 1009#endif
1010 1010
1011 p->thread.fp_save_area = NULL;
1012#ifdef CONFIG_ALTIVEC
1013 p->thread.vr_save_area = NULL;
1014#endif
1015
1011#ifdef CONFIG_PPC_STD_MMU_64 1016#ifdef CONFIG_PPC_STD_MMU_64
1012 if (mmu_has_feature(MMU_FTR_SLB)) { 1017 if (mmu_has_feature(MMU_FTR_SLB)) {
1013 unsigned long sp_vsid; 1018 unsigned long sp_vsid;
@@ -1113,12 +1118,12 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
1113#ifdef CONFIG_VSX 1118#ifdef CONFIG_VSX
1114 current->thread.used_vsr = 0; 1119 current->thread.used_vsr = 0;
1115#endif 1120#endif
1116 memset(current->thread.fpr, 0, sizeof(current->thread.fpr)); 1121 memset(&current->thread.fp_state, 0, sizeof(current->thread.fp_state));
1117 current->thread.fpscr.val = 0; 1122 current->thread.fp_save_area = NULL;
1118#ifdef CONFIG_ALTIVEC 1123#ifdef CONFIG_ALTIVEC
1119 memset(current->thread.vr, 0, sizeof(current->thread.vr)); 1124 memset(&current->thread.vr_state, 0, sizeof(current->thread.vr_state));
1120 memset(&current->thread.vscr, 0, sizeof(current->thread.vscr)); 1125 current->thread.vr_state.vscr.u[3] = 0x00010000; /* Java mode disabled */
1121 current->thread.vscr.u[3] = 0x00010000; /* Java mode disabled */ 1126 current->thread.vr_save_area = NULL;
1122 current->thread.vrsave = 0; 1127 current->thread.vrsave = 0;
1123 current->thread.used_vr = 0; 1128 current->thread.used_vr = 0;
1124#endif /* CONFIG_ALTIVEC */ 1129#endif /* CONFIG_ALTIVEC */
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 8d5d4e921a5e..1ca589c9ec6d 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -362,7 +362,7 @@ static int fpr_get(struct task_struct *target, const struct user_regset *regset,
362 void *kbuf, void __user *ubuf) 362 void *kbuf, void __user *ubuf)
363{ 363{
364#ifdef CONFIG_VSX 364#ifdef CONFIG_VSX
365 double buf[33]; 365 u64 buf[33];
366 int i; 366 int i;
367#endif 367#endif
368 flush_fp_to_thread(target); 368 flush_fp_to_thread(target);
@@ -371,15 +371,15 @@ static int fpr_get(struct task_struct *target, const struct user_regset *regset,
371 /* copy to local buffer then write that out */ 371 /* copy to local buffer then write that out */
372 for (i = 0; i < 32 ; i++) 372 for (i = 0; i < 32 ; i++)
373 buf[i] = target->thread.TS_FPR(i); 373 buf[i] = target->thread.TS_FPR(i);
374 memcpy(&buf[32], &target->thread.fpscr, sizeof(double)); 374 buf[32] = target->thread.fp_state.fpscr;
375 return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1); 375 return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
376 376
377#else 377#else
378 BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) != 378 BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
379 offsetof(struct thread_struct, TS_FPR(32))); 379 offsetof(struct thread_fp_state, fpr[32][0]));
380 380
381 return user_regset_copyout(&pos, &count, &kbuf, &ubuf, 381 return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
382 &target->thread.fpr, 0, -1); 382 &target->thread.fp_state, 0, -1);
383#endif 383#endif
384} 384}
385 385
@@ -388,7 +388,7 @@ static int fpr_set(struct task_struct *target, const struct user_regset *regset,
388 const void *kbuf, const void __user *ubuf) 388 const void *kbuf, const void __user *ubuf)
389{ 389{
390#ifdef CONFIG_VSX 390#ifdef CONFIG_VSX
391 double buf[33]; 391 u64 buf[33];
392 int i; 392 int i;
393#endif 393#endif
394 flush_fp_to_thread(target); 394 flush_fp_to_thread(target);
@@ -400,14 +400,14 @@ static int fpr_set(struct task_struct *target, const struct user_regset *regset,
400 return i; 400 return i;
401 for (i = 0; i < 32 ; i++) 401 for (i = 0; i < 32 ; i++)
402 target->thread.TS_FPR(i) = buf[i]; 402 target->thread.TS_FPR(i) = buf[i];
403 memcpy(&target->thread.fpscr, &buf[32], sizeof(double)); 403 target->thread.fp_state.fpscr = buf[32];
404 return 0; 404 return 0;
405#else 405#else
406 BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) != 406 BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
407 offsetof(struct thread_struct, TS_FPR(32))); 407 offsetof(struct thread_fp_state, fpr[32][0]));
408 408
409 return user_regset_copyin(&pos, &count, &kbuf, &ubuf, 409 return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
410 &target->thread.fpr, 0, -1); 410 &target->thread.fp_state, 0, -1);
411#endif 411#endif
412} 412}
413 413
@@ -440,11 +440,11 @@ static int vr_get(struct task_struct *target, const struct user_regset *regset,
440 440
441 flush_altivec_to_thread(target); 441 flush_altivec_to_thread(target);
442 442
443 BUILD_BUG_ON(offsetof(struct thread_struct, vscr) != 443 BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
444 offsetof(struct thread_struct, vr[32])); 444 offsetof(struct thread_vr_state, vr[32]));
445 445
446 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, 446 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
447 &target->thread.vr, 0, 447 &target->thread.vr_state, 0,
448 33 * sizeof(vector128)); 448 33 * sizeof(vector128));
449 if (!ret) { 449 if (!ret) {
450 /* 450 /*
@@ -471,11 +471,12 @@ static int vr_set(struct task_struct *target, const struct user_regset *regset,
471 471
472 flush_altivec_to_thread(target); 472 flush_altivec_to_thread(target);
473 473
474 BUILD_BUG_ON(offsetof(struct thread_struct, vscr) != 474 BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
475 offsetof(struct thread_struct, vr[32])); 475 offsetof(struct thread_vr_state, vr[32]));
476 476
477 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 477 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
478 &target->thread.vr, 0, 33 * sizeof(vector128)); 478 &target->thread.vr_state, 0,
479 33 * sizeof(vector128));
479 if (!ret && count > 0) { 480 if (!ret && count > 0) {
480 /* 481 /*
481 * We use only the first word of vrsave. 482 * We use only the first word of vrsave.
@@ -514,13 +515,13 @@ static int vsr_get(struct task_struct *target, const struct user_regset *regset,
514 unsigned int pos, unsigned int count, 515 unsigned int pos, unsigned int count,
515 void *kbuf, void __user *ubuf) 516 void *kbuf, void __user *ubuf)
516{ 517{
517 double buf[32]; 518 u64 buf[32];
518 int ret, i; 519 int ret, i;
519 520
520 flush_vsx_to_thread(target); 521 flush_vsx_to_thread(target);
521 522
522 for (i = 0; i < 32 ; i++) 523 for (i = 0; i < 32 ; i++)
523 buf[i] = target->thread.fpr[i][TS_VSRLOWOFFSET]; 524 buf[i] = target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET];
524 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, 525 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
525 buf, 0, 32 * sizeof(double)); 526 buf, 0, 32 * sizeof(double));
526 527
@@ -531,7 +532,7 @@ static int vsr_set(struct task_struct *target, const struct user_regset *regset,
531 unsigned int pos, unsigned int count, 532 unsigned int pos, unsigned int count,
532 const void *kbuf, const void __user *ubuf) 533 const void *kbuf, const void __user *ubuf)
533{ 534{
534 double buf[32]; 535 u64 buf[32];
535 int ret,i; 536 int ret,i;
536 537
537 flush_vsx_to_thread(target); 538 flush_vsx_to_thread(target);
@@ -539,7 +540,7 @@ static int vsr_set(struct task_struct *target, const struct user_regset *regset,
539 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 540 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
540 buf, 0, 32 * sizeof(double)); 541 buf, 0, 32 * sizeof(double));
541 for (i = 0; i < 32 ; i++) 542 for (i = 0; i < 32 ; i++)
542 target->thread.fpr[i][TS_VSRLOWOFFSET] = buf[i]; 543 target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
543 544
544 545
545 return ret; 546 return ret;
@@ -1554,10 +1555,10 @@ long arch_ptrace(struct task_struct *child, long request,
1554 1555
1555 flush_fp_to_thread(child); 1556 flush_fp_to_thread(child);
1556 if (fpidx < (PT_FPSCR - PT_FPR0)) 1557 if (fpidx < (PT_FPSCR - PT_FPR0))
1557 memcpy(&tmp, &child->thread.TS_FPR(fpidx), 1558 memcpy(&tmp, &child->thread.fp_state.fpr,
1558 sizeof(long)); 1559 sizeof(long));
1559 else 1560 else
1560 tmp = child->thread.fpscr.val; 1561 tmp = child->thread.fp_state.fpscr;
1561 } 1562 }
1562 ret = put_user(tmp, datalp); 1563 ret = put_user(tmp, datalp);
1563 break; 1564 break;
@@ -1587,10 +1588,10 @@ long arch_ptrace(struct task_struct *child, long request,
1587 1588
1588 flush_fp_to_thread(child); 1589 flush_fp_to_thread(child);
1589 if (fpidx < (PT_FPSCR - PT_FPR0)) 1590 if (fpidx < (PT_FPSCR - PT_FPR0))
1590 memcpy(&child->thread.TS_FPR(fpidx), &data, 1591 memcpy(&child->thread.fp_state.fpr, &data,
1591 sizeof(long)); 1592 sizeof(long));
1592 else 1593 else
1593 child->thread.fpscr.val = data; 1594 child->thread.fp_state.fpscr = data;
1594 ret = 0; 1595 ret = 0;
1595 } 1596 }
1596 break; 1597 break;
diff --git a/arch/powerpc/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c
index f51599e941c7..097f8dc426a0 100644
--- a/arch/powerpc/kernel/ptrace32.c
+++ b/arch/powerpc/kernel/ptrace32.c
@@ -43,7 +43,6 @@
43#define FPRNUMBER(i) (((i) - PT_FPR0) >> 1) 43#define FPRNUMBER(i) (((i) - PT_FPR0) >> 1)
44#define FPRHALF(i) (((i) - PT_FPR0) & 1) 44#define FPRHALF(i) (((i) - PT_FPR0) & 1)
45#define FPRINDEX(i) TS_FPRWIDTH * FPRNUMBER(i) * 2 + FPRHALF(i) 45#define FPRINDEX(i) TS_FPRWIDTH * FPRNUMBER(i) * 2 + FPRHALF(i)
46#define FPRINDEX_3264(i) (TS_FPRWIDTH * ((i) - PT_FPR0))
47 46
48long compat_arch_ptrace(struct task_struct *child, compat_long_t request, 47long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
49 compat_ulong_t caddr, compat_ulong_t cdata) 48 compat_ulong_t caddr, compat_ulong_t cdata)
@@ -105,7 +104,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
105 * to be an array of unsigned int (32 bits) - the 104 * to be an array of unsigned int (32 bits) - the
106 * index passed in is based on this assumption. 105 * index passed in is based on this assumption.
107 */ 106 */
108 tmp = ((unsigned int *)child->thread.fpr) 107 tmp = ((unsigned int *)child->thread.fp_state.fpr)
109 [FPRINDEX(index)]; 108 [FPRINDEX(index)];
110 } 109 }
111 ret = put_user((unsigned int)tmp, (u32 __user *)data); 110 ret = put_user((unsigned int)tmp, (u32 __user *)data);
@@ -147,8 +146,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
147 if (numReg >= PT_FPR0) { 146 if (numReg >= PT_FPR0) {
148 flush_fp_to_thread(child); 147 flush_fp_to_thread(child);
149 /* get 64 bit FPR */ 148 /* get 64 bit FPR */
150 tmp = ((u64 *)child->thread.fpr) 149 tmp = child->thread.fp_state.fpr[numReg - PT_FPR0][0];
151 [FPRINDEX_3264(numReg)];
152 } else { /* register within PT_REGS struct */ 150 } else { /* register within PT_REGS struct */
153 unsigned long tmp2; 151 unsigned long tmp2;
154 ret = ptrace_get_reg(child, numReg, &tmp2); 152 ret = ptrace_get_reg(child, numReg, &tmp2);
@@ -207,7 +205,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
207 * to be an array of unsigned int (32 bits) - the 205 * to be an array of unsigned int (32 bits) - the
208 * index passed in is based on this assumption. 206 * index passed in is based on this assumption.
209 */ 207 */
210 ((unsigned int *)child->thread.fpr) 208 ((unsigned int *)child->thread.fp_state.fpr)
211 [FPRINDEX(index)] = data; 209 [FPRINDEX(index)] = data;
212 ret = 0; 210 ret = 0;
213 } 211 }
@@ -251,8 +249,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
251 u64 *tmp; 249 u64 *tmp;
252 flush_fp_to_thread(child); 250 flush_fp_to_thread(child);
253 /* get 64 bit FPR ... */ 251 /* get 64 bit FPR ... */
254 tmp = &(((u64 *)child->thread.fpr) 252 tmp = &child->thread.fp_state.fpr[numReg - PT_FPR0][0];
255 [FPRINDEX_3264(numReg)]);
256 /* ... write the 32 bit part we want */ 253 /* ... write the 32 bit part we want */
257 ((u32 *)tmp)[index % 2] = data; 254 ((u32 *)tmp)[index % 2] = data;
258 ret = 0; 255 ret = 0;
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index b386b0be8d02..c094e28b3f10 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -265,27 +265,27 @@ struct rt_sigframe {
265unsigned long copy_fpr_to_user(void __user *to, 265unsigned long copy_fpr_to_user(void __user *to,
266 struct task_struct *task) 266 struct task_struct *task)
267{ 267{
268 double buf[ELF_NFPREG]; 268 u64 buf[ELF_NFPREG];
269 int i; 269 int i;
270 270
271 /* save FPR copy to local buffer then write to the thread_struct */ 271 /* save FPR copy to local buffer then write to the thread_struct */
272 for (i = 0; i < (ELF_NFPREG - 1) ; i++) 272 for (i = 0; i < (ELF_NFPREG - 1) ; i++)
273 buf[i] = task->thread.TS_FPR(i); 273 buf[i] = task->thread.TS_FPR(i);
274 memcpy(&buf[i], &task->thread.fpscr, sizeof(double)); 274 buf[i] = task->thread.fp_state.fpscr;
275 return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double)); 275 return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
276} 276}
277 277
278unsigned long copy_fpr_from_user(struct task_struct *task, 278unsigned long copy_fpr_from_user(struct task_struct *task,
279 void __user *from) 279 void __user *from)
280{ 280{
281 double buf[ELF_NFPREG]; 281 u64 buf[ELF_NFPREG];
282 int i; 282 int i;
283 283
284 if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double))) 284 if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
285 return 1; 285 return 1;
286 for (i = 0; i < (ELF_NFPREG - 1) ; i++) 286 for (i = 0; i < (ELF_NFPREG - 1) ; i++)
287 task->thread.TS_FPR(i) = buf[i]; 287 task->thread.TS_FPR(i) = buf[i];
288 memcpy(&task->thread.fpscr, &buf[i], sizeof(double)); 288 task->thread.fp_state.fpscr = buf[i];
289 289
290 return 0; 290 return 0;
291} 291}
@@ -293,25 +293,25 @@ unsigned long copy_fpr_from_user(struct task_struct *task,
293unsigned long copy_vsx_to_user(void __user *to, 293unsigned long copy_vsx_to_user(void __user *to,
294 struct task_struct *task) 294 struct task_struct *task)
295{ 295{
296 double buf[ELF_NVSRHALFREG]; 296 u64 buf[ELF_NVSRHALFREG];
297 int i; 297 int i;
298 298
299 /* save FPR copy to local buffer then write to the thread_struct */ 299 /* save FPR copy to local buffer then write to the thread_struct */
300 for (i = 0; i < ELF_NVSRHALFREG; i++) 300 for (i = 0; i < ELF_NVSRHALFREG; i++)
301 buf[i] = task->thread.fpr[i][TS_VSRLOWOFFSET]; 301 buf[i] = task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET];
302 return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double)); 302 return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
303} 303}
304 304
305unsigned long copy_vsx_from_user(struct task_struct *task, 305unsigned long copy_vsx_from_user(struct task_struct *task,
306 void __user *from) 306 void __user *from)
307{ 307{
308 double buf[ELF_NVSRHALFREG]; 308 u64 buf[ELF_NVSRHALFREG];
309 int i; 309 int i;
310 310
311 if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double))) 311 if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
312 return 1; 312 return 1;
313 for (i = 0; i < ELF_NVSRHALFREG ; i++) 313 for (i = 0; i < ELF_NVSRHALFREG ; i++)
314 task->thread.fpr[i][TS_VSRLOWOFFSET] = buf[i]; 314 task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
315 return 0; 315 return 0;
316} 316}
317 317
@@ -319,27 +319,27 @@ unsigned long copy_vsx_from_user(struct task_struct *task,
319unsigned long copy_transact_fpr_to_user(void __user *to, 319unsigned long copy_transact_fpr_to_user(void __user *to,
320 struct task_struct *task) 320 struct task_struct *task)
321{ 321{
322 double buf[ELF_NFPREG]; 322 u64 buf[ELF_NFPREG];
323 int i; 323 int i;
324 324
325 /* save FPR copy to local buffer then write to the thread_struct */ 325 /* save FPR copy to local buffer then write to the thread_struct */
326 for (i = 0; i < (ELF_NFPREG - 1) ; i++) 326 for (i = 0; i < (ELF_NFPREG - 1) ; i++)
327 buf[i] = task->thread.TS_TRANS_FPR(i); 327 buf[i] = task->thread.TS_TRANS_FPR(i);
328 memcpy(&buf[i], &task->thread.transact_fpscr, sizeof(double)); 328 buf[i] = task->thread.transact_fp.fpscr;
329 return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double)); 329 return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
330} 330}
331 331
332unsigned long copy_transact_fpr_from_user(struct task_struct *task, 332unsigned long copy_transact_fpr_from_user(struct task_struct *task,
333 void __user *from) 333 void __user *from)
334{ 334{
335 double buf[ELF_NFPREG]; 335 u64 buf[ELF_NFPREG];
336 int i; 336 int i;
337 337
338 if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double))) 338 if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
339 return 1; 339 return 1;
340 for (i = 0; i < (ELF_NFPREG - 1) ; i++) 340 for (i = 0; i < (ELF_NFPREG - 1) ; i++)
341 task->thread.TS_TRANS_FPR(i) = buf[i]; 341 task->thread.TS_TRANS_FPR(i) = buf[i];
342 memcpy(&task->thread.transact_fpscr, &buf[i], sizeof(double)); 342 task->thread.transact_fp.fpscr = buf[i];
343 343
344 return 0; 344 return 0;
345} 345}
@@ -347,25 +347,25 @@ unsigned long copy_transact_fpr_from_user(struct task_struct *task,
347unsigned long copy_transact_vsx_to_user(void __user *to, 347unsigned long copy_transact_vsx_to_user(void __user *to,
348 struct task_struct *task) 348 struct task_struct *task)
349{ 349{
350 double buf[ELF_NVSRHALFREG]; 350 u64 buf[ELF_NVSRHALFREG];
351 int i; 351 int i;
352 352
353 /* save FPR copy to local buffer then write to the thread_struct */ 353 /* save FPR copy to local buffer then write to the thread_struct */
354 for (i = 0; i < ELF_NVSRHALFREG; i++) 354 for (i = 0; i < ELF_NVSRHALFREG; i++)
355 buf[i] = task->thread.transact_fpr[i][TS_VSRLOWOFFSET]; 355 buf[i] = task->thread.transact_fp.fpr[i][TS_VSRLOWOFFSET];
356 return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double)); 356 return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
357} 357}
358 358
359unsigned long copy_transact_vsx_from_user(struct task_struct *task, 359unsigned long copy_transact_vsx_from_user(struct task_struct *task,
360 void __user *from) 360 void __user *from)
361{ 361{
362 double buf[ELF_NVSRHALFREG]; 362 u64 buf[ELF_NVSRHALFREG];
363 int i; 363 int i;
364 364
365 if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double))) 365 if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
366 return 1; 366 return 1;
367 for (i = 0; i < ELF_NVSRHALFREG ; i++) 367 for (i = 0; i < ELF_NVSRHALFREG ; i++)
368 task->thread.transact_fpr[i][TS_VSRLOWOFFSET] = buf[i]; 368 task->thread.transact_fp.fpr[i][TS_VSRLOWOFFSET] = buf[i];
369 return 0; 369 return 0;
370} 370}
371#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ 371#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
@@ -373,14 +373,14 @@ unsigned long copy_transact_vsx_from_user(struct task_struct *task,
373inline unsigned long copy_fpr_to_user(void __user *to, 373inline unsigned long copy_fpr_to_user(void __user *to,
374 struct task_struct *task) 374 struct task_struct *task)
375{ 375{
376 return __copy_to_user(to, task->thread.fpr, 376 return __copy_to_user(to, task->thread.fp_state.fpr,
377 ELF_NFPREG * sizeof(double)); 377 ELF_NFPREG * sizeof(double));
378} 378}
379 379
380inline unsigned long copy_fpr_from_user(struct task_struct *task, 380inline unsigned long copy_fpr_from_user(struct task_struct *task,
381 void __user *from) 381 void __user *from)
382{ 382{
383 return __copy_from_user(task->thread.fpr, from, 383 return __copy_from_user(task->thread.fp_state.fpr, from,
384 ELF_NFPREG * sizeof(double)); 384 ELF_NFPREG * sizeof(double));
385} 385}
386 386
@@ -388,14 +388,14 @@ inline unsigned long copy_fpr_from_user(struct task_struct *task,
388inline unsigned long copy_transact_fpr_to_user(void __user *to, 388inline unsigned long copy_transact_fpr_to_user(void __user *to,
389 struct task_struct *task) 389 struct task_struct *task)
390{ 390{
391 return __copy_to_user(to, task->thread.transact_fpr, 391 return __copy_to_user(to, task->thread.transact_fp.fpr,
392 ELF_NFPREG * sizeof(double)); 392 ELF_NFPREG * sizeof(double));
393} 393}
394 394
395inline unsigned long copy_transact_fpr_from_user(struct task_struct *task, 395inline unsigned long copy_transact_fpr_from_user(struct task_struct *task,
396 void __user *from) 396 void __user *from)
397{ 397{
398 return __copy_from_user(task->thread.transact_fpr, from, 398 return __copy_from_user(task->thread.transact_fp.fpr, from,
399 ELF_NFPREG * sizeof(double)); 399 ELF_NFPREG * sizeof(double));
400} 400}
401#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ 401#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
@@ -423,7 +423,7 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
423 /* save altivec registers */ 423 /* save altivec registers */
424 if (current->thread.used_vr) { 424 if (current->thread.used_vr) {
425 flush_altivec_to_thread(current); 425 flush_altivec_to_thread(current);
426 if (__copy_to_user(&frame->mc_vregs, current->thread.vr, 426 if (__copy_to_user(&frame->mc_vregs, &current->thread.vr_state,
427 ELF_NVRREG * sizeof(vector128))) 427 ELF_NVRREG * sizeof(vector128)))
428 return 1; 428 return 1;
429 /* set MSR_VEC in the saved MSR value to indicate that 429 /* set MSR_VEC in the saved MSR value to indicate that
@@ -534,17 +534,17 @@ static int save_tm_user_regs(struct pt_regs *regs,
534 /* save altivec registers */ 534 /* save altivec registers */
535 if (current->thread.used_vr) { 535 if (current->thread.used_vr) {
536 flush_altivec_to_thread(current); 536 flush_altivec_to_thread(current);
537 if (__copy_to_user(&frame->mc_vregs, current->thread.vr, 537 if (__copy_to_user(&frame->mc_vregs, &current->thread.vr_state,
538 ELF_NVRREG * sizeof(vector128))) 538 ELF_NVRREG * sizeof(vector128)))
539 return 1; 539 return 1;
540 if (msr & MSR_VEC) { 540 if (msr & MSR_VEC) {
541 if (__copy_to_user(&tm_frame->mc_vregs, 541 if (__copy_to_user(&tm_frame->mc_vregs,
542 current->thread.transact_vr, 542 &current->thread.transact_vr,
543 ELF_NVRREG * sizeof(vector128))) 543 ELF_NVRREG * sizeof(vector128)))
544 return 1; 544 return 1;
545 } else { 545 } else {
546 if (__copy_to_user(&tm_frame->mc_vregs, 546 if (__copy_to_user(&tm_frame->mc_vregs,
547 current->thread.vr, 547 &current->thread.vr_state,
548 ELF_NVRREG * sizeof(vector128))) 548 ELF_NVRREG * sizeof(vector128)))
549 return 1; 549 return 1;
550 } 550 }
@@ -692,11 +692,12 @@ static long restore_user_regs(struct pt_regs *regs,
692 regs->msr &= ~MSR_VEC; 692 regs->msr &= ~MSR_VEC;
693 if (msr & MSR_VEC) { 693 if (msr & MSR_VEC) {
694 /* restore altivec registers from the stack */ 694 /* restore altivec registers from the stack */
695 if (__copy_from_user(current->thread.vr, &sr->mc_vregs, 695 if (__copy_from_user(&current->thread.vr_state, &sr->mc_vregs,
696 sizeof(sr->mc_vregs))) 696 sizeof(sr->mc_vregs)))
697 return 1; 697 return 1;
698 } else if (current->thread.used_vr) 698 } else if (current->thread.used_vr)
699 memset(current->thread.vr, 0, ELF_NVRREG * sizeof(vector128)); 699 memset(&current->thread.vr_state, 0,
700 ELF_NVRREG * sizeof(vector128));
700 701
701 /* Always get VRSAVE back */ 702 /* Always get VRSAVE back */
702 if (__get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32])) 703 if (__get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32]))
@@ -722,7 +723,7 @@ static long restore_user_regs(struct pt_regs *regs,
722 return 1; 723 return 1;
723 } else if (current->thread.used_vsr) 724 } else if (current->thread.used_vsr)
724 for (i = 0; i < 32 ; i++) 725 for (i = 0; i < 32 ; i++)
725 current->thread.fpr[i][TS_VSRLOWOFFSET] = 0; 726 current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0;
726#endif /* CONFIG_VSX */ 727#endif /* CONFIG_VSX */
727 /* 728 /*
728 * force the process to reload the FP registers from 729 * force the process to reload the FP registers from
@@ -798,15 +799,16 @@ static long restore_tm_user_regs(struct pt_regs *regs,
798 regs->msr &= ~MSR_VEC; 799 regs->msr &= ~MSR_VEC;
799 if (msr & MSR_VEC) { 800 if (msr & MSR_VEC) {
800 /* restore altivec registers from the stack */ 801 /* restore altivec registers from the stack */
801 if (__copy_from_user(current->thread.vr, &sr->mc_vregs, 802 if (__copy_from_user(&current->thread.vr_state, &sr->mc_vregs,
802 sizeof(sr->mc_vregs)) || 803 sizeof(sr->mc_vregs)) ||
803 __copy_from_user(current->thread.transact_vr, 804 __copy_from_user(&current->thread.transact_vr,
804 &tm_sr->mc_vregs, 805 &tm_sr->mc_vregs,
805 sizeof(sr->mc_vregs))) 806 sizeof(sr->mc_vregs)))
806 return 1; 807 return 1;
807 } else if (current->thread.used_vr) { 808 } else if (current->thread.used_vr) {
808 memset(current->thread.vr, 0, ELF_NVRREG * sizeof(vector128)); 809 memset(&current->thread.vr_state, 0,
809 memset(current->thread.transact_vr, 0, 810 ELF_NVRREG * sizeof(vector128));
811 memset(&current->thread.transact_vr, 0,
810 ELF_NVRREG * sizeof(vector128)); 812 ELF_NVRREG * sizeof(vector128));
811 } 813 }
812 814
@@ -838,8 +840,8 @@ static long restore_tm_user_regs(struct pt_regs *regs,
838 return 1; 840 return 1;
839 } else if (current->thread.used_vsr) 841 } else if (current->thread.used_vsr)
840 for (i = 0; i < 32 ; i++) { 842 for (i = 0; i < 32 ; i++) {
841 current->thread.fpr[i][TS_VSRLOWOFFSET] = 0; 843 current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0;
842 current->thread.transact_fpr[i][TS_VSRLOWOFFSET] = 0; 844 current->thread.transact_fp.fpr[i][TS_VSRLOWOFFSET] = 0;
843 } 845 }
844#endif /* CONFIG_VSX */ 846#endif /* CONFIG_VSX */
845 847
@@ -1030,7 +1032,7 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
1030 if (__put_user(0, &rt_sf->uc.uc_link)) 1032 if (__put_user(0, &rt_sf->uc.uc_link))
1031 goto badframe; 1033 goto badframe;
1032 1034
1033 current->thread.fpscr.val = 0; /* turn off all fp exceptions */ 1035 current->thread.fp_state.fpscr = 0; /* turn off all fp exceptions */
1034 1036
1035 /* create a stack frame for the caller of the handler */ 1037 /* create a stack frame for the caller of the handler */
1036 newsp = ((unsigned long)rt_sf) - (__SIGNAL_FRAMESIZE + 16); 1038 newsp = ((unsigned long)rt_sf) - (__SIGNAL_FRAMESIZE + 16);
@@ -1463,7 +1465,7 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
1463 1465
1464 regs->link = tramp; 1466 regs->link = tramp;
1465 1467
1466 current->thread.fpscr.val = 0; /* turn off all fp exceptions */ 1468 current->thread.fp_state.fpscr = 0; /* turn off all fp exceptions */
1467 1469
1468 /* create a stack frame for the caller of the handler */ 1470 /* create a stack frame for the caller of the handler */
1469 newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE; 1471 newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE;
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 8b51b0278106..b3c615764c9b 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -103,7 +103,8 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
103 if (current->thread.used_vr) { 103 if (current->thread.used_vr) {
104 flush_altivec_to_thread(current); 104 flush_altivec_to_thread(current);
105 /* Copy 33 vec registers (vr0..31 and vscr) to the stack */ 105 /* Copy 33 vec registers (vr0..31 and vscr) to the stack */
106 err |= __copy_to_user(v_regs, current->thread.vr, 33 * sizeof(vector128)); 106 err |= __copy_to_user(v_regs, &current->thread.vr_state,
107 33 * sizeof(vector128));
107 /* set MSR_VEC in the MSR value in the frame to indicate that sc->v_reg) 108 /* set MSR_VEC in the MSR value in the frame to indicate that sc->v_reg)
108 * contains valid data. 109 * contains valid data.
109 */ 110 */
@@ -195,18 +196,18 @@ static long setup_tm_sigcontexts(struct sigcontext __user *sc,
195 if (current->thread.used_vr) { 196 if (current->thread.used_vr) {
196 flush_altivec_to_thread(current); 197 flush_altivec_to_thread(current);
197 /* Copy 33 vec registers (vr0..31 and vscr) to the stack */ 198 /* Copy 33 vec registers (vr0..31 and vscr) to the stack */
198 err |= __copy_to_user(v_regs, current->thread.vr, 199 err |= __copy_to_user(v_regs, &current->thread.vr_state,
199 33 * sizeof(vector128)); 200 33 * sizeof(vector128));
200 /* If VEC was enabled there are transactional VRs valid too, 201 /* If VEC was enabled there are transactional VRs valid too,
201 * else they're a copy of the checkpointed VRs. 202 * else they're a copy of the checkpointed VRs.
202 */ 203 */
203 if (msr & MSR_VEC) 204 if (msr & MSR_VEC)
204 err |= __copy_to_user(tm_v_regs, 205 err |= __copy_to_user(tm_v_regs,
205 current->thread.transact_vr, 206 &current->thread.transact_vr,
206 33 * sizeof(vector128)); 207 33 * sizeof(vector128));
207 else 208 else
208 err |= __copy_to_user(tm_v_regs, 209 err |= __copy_to_user(tm_v_regs,
209 current->thread.vr, 210 &current->thread.vr_state,
210 33 * sizeof(vector128)); 211 33 * sizeof(vector128));
211 212
212 /* set MSR_VEC in the MSR value in the frame to indicate 213 /* set MSR_VEC in the MSR value in the frame to indicate
@@ -349,10 +350,10 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig,
349 return -EFAULT; 350 return -EFAULT;
350 /* Copy 33 vec registers (vr0..31 and vscr) from the stack */ 351 /* Copy 33 vec registers (vr0..31 and vscr) from the stack */
351 if (v_regs != NULL && (msr & MSR_VEC) != 0) 352 if (v_regs != NULL && (msr & MSR_VEC) != 0)
352 err |= __copy_from_user(current->thread.vr, v_regs, 353 err |= __copy_from_user(&current->thread.vr_state, v_regs,
353 33 * sizeof(vector128)); 354 33 * sizeof(vector128));
354 else if (current->thread.used_vr) 355 else if (current->thread.used_vr)
355 memset(current->thread.vr, 0, 33 * sizeof(vector128)); 356 memset(&current->thread.vr_state, 0, 33 * sizeof(vector128));
356 /* Always get VRSAVE back */ 357 /* Always get VRSAVE back */
357 if (v_regs != NULL) 358 if (v_regs != NULL)
358 err |= __get_user(current->thread.vrsave, (u32 __user *)&v_regs[33]); 359 err |= __get_user(current->thread.vrsave, (u32 __user *)&v_regs[33]);
@@ -374,7 +375,7 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig,
374 err |= copy_vsx_from_user(current, v_regs); 375 err |= copy_vsx_from_user(current, v_regs);
375 else 376 else
376 for (i = 0; i < 32 ; i++) 377 for (i = 0; i < 32 ; i++)
377 current->thread.fpr[i][TS_VSRLOWOFFSET] = 0; 378 current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0;
378#endif 379#endif
379 return err; 380 return err;
380} 381}
@@ -468,14 +469,14 @@ static long restore_tm_sigcontexts(struct pt_regs *regs,
468 return -EFAULT; 469 return -EFAULT;
469 /* Copy 33 vec registers (vr0..31 and vscr) from the stack */ 470 /* Copy 33 vec registers (vr0..31 and vscr) from the stack */
470 if (v_regs != NULL && tm_v_regs != NULL && (msr & MSR_VEC) != 0) { 471 if (v_regs != NULL && tm_v_regs != NULL && (msr & MSR_VEC) != 0) {
471 err |= __copy_from_user(current->thread.vr, v_regs, 472 err |= __copy_from_user(&current->thread.vr_state, v_regs,
472 33 * sizeof(vector128)); 473 33 * sizeof(vector128));
473 err |= __copy_from_user(current->thread.transact_vr, tm_v_regs, 474 err |= __copy_from_user(&current->thread.transact_vr, tm_v_regs,
474 33 * sizeof(vector128)); 475 33 * sizeof(vector128));
475 } 476 }
476 else if (current->thread.used_vr) { 477 else if (current->thread.used_vr) {
477 memset(current->thread.vr, 0, 33 * sizeof(vector128)); 478 memset(&current->thread.vr_state, 0, 33 * sizeof(vector128));
478 memset(current->thread.transact_vr, 0, 33 * sizeof(vector128)); 479 memset(&current->thread.transact_vr, 0, 33 * sizeof(vector128));
479 } 480 }
480 /* Always get VRSAVE back */ 481 /* Always get VRSAVE back */
481 if (v_regs != NULL && tm_v_regs != NULL) { 482 if (v_regs != NULL && tm_v_regs != NULL) {
@@ -507,8 +508,8 @@ static long restore_tm_sigcontexts(struct pt_regs *regs,
507 err |= copy_transact_vsx_from_user(current, tm_v_regs); 508 err |= copy_transact_vsx_from_user(current, tm_v_regs);
508 } else { 509 } else {
509 for (i = 0; i < 32 ; i++) { 510 for (i = 0; i < 32 ; i++) {
510 current->thread.fpr[i][TS_VSRLOWOFFSET] = 0; 511 current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0;
511 current->thread.transact_fpr[i][TS_VSRLOWOFFSET] = 0; 512 current->thread.transact_fp.fpr[i][TS_VSRLOWOFFSET] = 0;
512 } 513 }
513 } 514 }
514#endif 515#endif
@@ -747,7 +748,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
747 goto badframe; 748 goto badframe;
748 749
749 /* Make sure signal handler doesn't get spurious FP exceptions */ 750 /* Make sure signal handler doesn't get spurious FP exceptions */
750 current->thread.fpscr.val = 0; 751 current->thread.fp_state.fpscr = 0;
751#ifdef CONFIG_PPC_TRANSACTIONAL_MEM 752#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
752 /* Remove TM bits from thread's MSR. The MSR in the sigcontext 753 /* Remove TM bits from thread's MSR. The MSR in the sigcontext
753 * just indicates to userland that we were doing a transaction, but we 754 * just indicates to userland that we were doing a transaction, but we
diff --git a/arch/powerpc/kernel/tm.S b/arch/powerpc/kernel/tm.S
index cd809eaa8b5c..761af4f0a632 100644
--- a/arch/powerpc/kernel/tm.S
+++ b/arch/powerpc/kernel/tm.S
@@ -12,16 +12,15 @@
12#include <asm/reg.h> 12#include <asm/reg.h>
13 13
14#ifdef CONFIG_VSX 14#ifdef CONFIG_VSX
15/* See fpu.S, this is very similar but to save/restore checkpointed FPRs/VSRs */ 15/* See fpu.S, this is borrowed from there */
16#define __SAVE_32FPRS_VSRS_TRANSACT(n,c,base) \ 16#define __SAVE_32FPRS_VSRS(n,c,base) \
17BEGIN_FTR_SECTION \ 17BEGIN_FTR_SECTION \
18 b 2f; \ 18 b 2f; \
19END_FTR_SECTION_IFSET(CPU_FTR_VSX); \ 19END_FTR_SECTION_IFSET(CPU_FTR_VSX); \
20 SAVE_32FPRS_TRANSACT(n,base); \ 20 SAVE_32FPRS(n,base); \
21 b 3f; \ 21 b 3f; \
222: SAVE_32VSRS_TRANSACT(n,c,base); \ 222: SAVE_32VSRS(n,c,base); \
233: 233:
24/* ...and this is just plain borrowed from there. */
25#define __REST_32FPRS_VSRS(n,c,base) \ 24#define __REST_32FPRS_VSRS(n,c,base) \
26BEGIN_FTR_SECTION \ 25BEGIN_FTR_SECTION \
27 b 2f; \ 26 b 2f; \
@@ -31,11 +30,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX); \
312: REST_32VSRS(n,c,base); \ 302: REST_32VSRS(n,c,base); \
323: 313:
33#else 32#else
34#define __SAVE_32FPRS_VSRS_TRANSACT(n,c,base) SAVE_32FPRS_TRANSACT(n, base) 33#define __SAVE_32FPRS_VSRS(n,c,base) SAVE_32FPRS(n, base)
35#define __REST_32FPRS_VSRS(n,c,base) REST_32FPRS(n, base) 34#define __REST_32FPRS_VSRS(n,c,base) REST_32FPRS(n, base)
36#endif 35#endif
37#define SAVE_32FPRS_VSRS_TRANSACT(n,c,base) \ 36#define SAVE_32FPRS_VSRS(n,c,base) \
38 __SAVE_32FPRS_VSRS_TRANSACT(n,__REG_##c,__REG_##base) 37 __SAVE_32FPRS_VSRS(n,__REG_##c,__REG_##base)
39#define REST_32FPRS_VSRS(n,c,base) \ 38#define REST_32FPRS_VSRS(n,c,base) \
40 __REST_32FPRS_VSRS(n,__REG_##c,__REG_##base) 39 __REST_32FPRS_VSRS(n,__REG_##c,__REG_##base)
41 40
@@ -157,10 +156,11 @@ _GLOBAL(tm_reclaim)
157 andis. r0, r4, MSR_VEC@h 156 andis. r0, r4, MSR_VEC@h
158 beq dont_backup_vec 157 beq dont_backup_vec
159 158
160 SAVE_32VRS_TRANSACT(0, r6, r3) /* r6 scratch, r3 thread */ 159 addi r7, r3, THREAD_TRANSACT_VRSTATE
160 SAVE_32VRS(0, r6, r7) /* r6 scratch, r7 transact vr state */
161 mfvscr vr0 161 mfvscr vr0
162 li r6, THREAD_TRANSACT_VSCR 162 li r6, VRSTATE_VSCR
163 stvx vr0, r3, r6 163 stvx vr0, r7, r6
164dont_backup_vec: 164dont_backup_vec:
165 mfspr r0, SPRN_VRSAVE 165 mfspr r0, SPRN_VRSAVE
166 std r0, THREAD_TRANSACT_VRSAVE(r3) 166 std r0, THREAD_TRANSACT_VRSAVE(r3)
@@ -168,10 +168,11 @@ dont_backup_vec:
168 andi. r0, r4, MSR_FP 168 andi. r0, r4, MSR_FP
169 beq dont_backup_fp 169 beq dont_backup_fp
170 170
171 SAVE_32FPRS_VSRS_TRANSACT(0, R6, R3) /* r6 scratch, r3 thread */ 171 addi r7, r3, THREAD_TRANSACT_FPSTATE
172 SAVE_32FPRS_VSRS(0, R6, R7) /* r6 scratch, r7 transact fp state */
172 173
173 mffs fr0 174 mffs fr0
174 stfd fr0,THREAD_TRANSACT_FPSCR(r3) 175 stfd fr0,FPSTATE_FPSCR(r7)
175 176
176dont_backup_fp: 177dont_backup_fp:
177 /* The moment we treclaim, ALL of our GPRs will switch 178 /* The moment we treclaim, ALL of our GPRs will switch
@@ -358,10 +359,11 @@ _GLOBAL(tm_recheckpoint)
358 andis. r0, r4, MSR_VEC@h 359 andis. r0, r4, MSR_VEC@h
359 beq dont_restore_vec 360 beq dont_restore_vec
360 361
361 li r5, THREAD_VSCR 362 addi r8, r3, THREAD_VRSTATE
362 lvx vr0, r3, r5 363 li r5, VRSTATE_VSCR
364 lvx vr0, r8, r5
363 mtvscr vr0 365 mtvscr vr0
364 REST_32VRS(0, r5, r3) /* r5 scratch, r3 THREAD ptr */ 366 REST_32VRS(0, r5, r8) /* r5 scratch, r8 ptr */
365dont_restore_vec: 367dont_restore_vec:
366 ld r5, THREAD_VRSAVE(r3) 368 ld r5, THREAD_VRSAVE(r3)
367 mtspr SPRN_VRSAVE, r5 369 mtspr SPRN_VRSAVE, r5
@@ -370,9 +372,10 @@ dont_restore_vec:
370 andi. r0, r4, MSR_FP 372 andi. r0, r4, MSR_FP
371 beq dont_restore_fp 373 beq dont_restore_fp
372 374
373 lfd fr0, THREAD_FPSCR(r3) 375 addi r8, r3, THREAD_FPSTATE
376 lfd fr0, FPSTATE_FPSCR(r8)
374 MTFSF_L(fr0) 377 MTFSF_L(fr0)
375 REST_32FPRS_VSRS(0, R4, R3) 378 REST_32FPRS_VSRS(0, R4, R8)
376 379
377dont_restore_fp: 380dont_restore_fp:
378 mtmsr r6 /* FP/Vec off again! */ 381 mtmsr r6 /* FP/Vec off again! */
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index f783c932faeb..f0a6814007a5 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -816,7 +816,7 @@ static void parse_fpe(struct pt_regs *regs)
816 816
817 flush_fp_to_thread(current); 817 flush_fp_to_thread(current);
818 818
819 code = __parse_fpscr(current->thread.fpscr.val); 819 code = __parse_fpscr(current->thread.fp_state.fpscr);
820 820
821 _exception(SIGFPE, regs, code, regs->nip); 821 _exception(SIGFPE, regs, code, regs->nip);
822} 822}
@@ -1069,7 +1069,7 @@ static int emulate_math(struct pt_regs *regs)
1069 return 0; 1069 return 0;
1070 case 1: { 1070 case 1: {
1071 int code = 0; 1071 int code = 0;
1072 code = __parse_fpscr(current->thread.fpscr.val); 1072 code = __parse_fpscr(current->thread.fp_state.fpscr);
1073 _exception(SIGFPE, regs, code, regs->nip); 1073 _exception(SIGFPE, regs, code, regs->nip);
1074 return 0; 1074 return 0;
1075 } 1075 }
@@ -1371,8 +1371,6 @@ void facility_unavailable_exception(struct pt_regs *regs)
1371 1371
1372#ifdef CONFIG_PPC_TRANSACTIONAL_MEM 1372#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1373 1373
1374extern void do_load_up_fpu(struct pt_regs *regs);
1375
1376void fp_unavailable_tm(struct pt_regs *regs) 1374void fp_unavailable_tm(struct pt_regs *regs)
1377{ 1375{
1378 /* Note: This does not handle any kind of FP laziness. */ 1376 /* Note: This does not handle any kind of FP laziness. */
@@ -1403,8 +1401,6 @@ void fp_unavailable_tm(struct pt_regs *regs)
1403} 1401}
1404 1402
1405#ifdef CONFIG_ALTIVEC 1403#ifdef CONFIG_ALTIVEC
1406extern void do_load_up_altivec(struct pt_regs *regs);
1407
1408void altivec_unavailable_tm(struct pt_regs *regs) 1404void altivec_unavailable_tm(struct pt_regs *regs)
1409{ 1405{
1410 /* See the comments in fp_unavailable_tm(). This function operates 1406 /* See the comments in fp_unavailable_tm(). This function operates
@@ -1634,7 +1630,7 @@ void altivec_assist_exception(struct pt_regs *regs)
1634 /* XXX quick hack for now: set the non-Java bit in the VSCR */ 1630 /* XXX quick hack for now: set the non-Java bit in the VSCR */
1635 printk_ratelimited(KERN_ERR "Unrecognized altivec instruction " 1631 printk_ratelimited(KERN_ERR "Unrecognized altivec instruction "
1636 "in %s at %lx\n", current->comm, regs->nip); 1632 "in %s at %lx\n", current->comm, regs->nip);
1637 current->thread.vscr.u[3] |= 0x10000; 1633 current->thread.vr_state.vscr.u[3] |= 0x10000;
1638 } 1634 }
1639} 1635}
1640#endif /* CONFIG_ALTIVEC */ 1636#endif /* CONFIG_ALTIVEC */
diff --git a/arch/powerpc/kernel/vecemu.c b/arch/powerpc/kernel/vecemu.c
index 604d0947cb20..c4bfadb2606b 100644
--- a/arch/powerpc/kernel/vecemu.c
+++ b/arch/powerpc/kernel/vecemu.c
@@ -271,7 +271,7 @@ int emulate_altivec(struct pt_regs *regs)
271 vb = (instr >> 11) & 0x1f; 271 vb = (instr >> 11) & 0x1f;
272 vc = (instr >> 6) & 0x1f; 272 vc = (instr >> 6) & 0x1f;
273 273
274 vrs = current->thread.vr; 274 vrs = current->thread.vr_state.vr;
275 switch (instr & 0x3f) { 275 switch (instr & 0x3f) {
276 case 10: 276 case 10:
277 switch (vc) { 277 switch (vc) {
@@ -320,12 +320,12 @@ int emulate_altivec(struct pt_regs *regs)
320 case 14: /* vctuxs */ 320 case 14: /* vctuxs */
321 for (i = 0; i < 4; ++i) 321 for (i = 0; i < 4; ++i)
322 vrs[vd].u[i] = ctuxs(vrs[vb].u[i], va, 322 vrs[vd].u[i] = ctuxs(vrs[vb].u[i], va,
323 &current->thread.vscr.u[3]); 323 &current->thread.vr_state.vscr.u[3]);
324 break; 324 break;
325 case 15: /* vctsxs */ 325 case 15: /* vctsxs */
326 for (i = 0; i < 4; ++i) 326 for (i = 0; i < 4; ++i)
327 vrs[vd].u[i] = ctsxs(vrs[vb].u[i], va, 327 vrs[vd].u[i] = ctsxs(vrs[vb].u[i], va,
328 &current->thread.vscr.u[3]); 328 &current->thread.vr_state.vscr.u[3]);
329 break; 329 break;
330 default: 330 default:
331 return -EINVAL; 331 return -EINVAL;
diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S
index 9e20999aaef2..eacda4eea2d7 100644
--- a/arch/powerpc/kernel/vector.S
+++ b/arch/powerpc/kernel/vector.S
@@ -8,29 +8,6 @@
8#include <asm/ptrace.h> 8#include <asm/ptrace.h>
9 9
10#ifdef CONFIG_PPC_TRANSACTIONAL_MEM 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) 11/* void do_load_up_transact_altivec(struct thread_struct *thread)
35 * 12 *
36 * This is similar to load_up_altivec but for the transactional version of the 13 * This is similar to load_up_altivec but for the transactional version of the
@@ -46,10 +23,11 @@ _GLOBAL(do_load_up_transact_altivec)
46 li r4,1 23 li r4,1
47 stw r4,THREAD_USED_VR(r3) 24 stw r4,THREAD_USED_VR(r3)
48 25
49 li r10,THREAD_TRANSACT_VSCR 26 li r10,THREAD_TRANSACT_VRSTATE+VRSTATE_VSCR
50 lvx vr0,r10,r3 27 lvx vr0,r10,r3
51 mtvscr vr0 28 mtvscr vr0
52 REST_32VRS_TRANSACT(0,r4,r3) 29 addi r10,r3,THREAD_TRANSACT_VRSTATE
30 REST_32VRS(0,r4,r10)
53 31
54 /* Disable VEC again. */ 32 /* Disable VEC again. */
55 MTMSRD(r6) 33 MTMSRD(r6)
@@ -59,7 +37,28 @@ _GLOBAL(do_load_up_transact_altivec)
59#endif 37#endif
60 38
61/* 39/*
62 * load_up_altivec(unused, unused, tsk) 40 * Load state from memory into VMX registers including VSCR.
41 * Assumes the caller has enabled VMX in the MSR.
42 */
43_GLOBAL(load_vr_state)
44 li r4,VRSTATE_VSCR
45 lvx vr0,r4,r3
46 mtvscr vr0
47 REST_32VRS(0,r4,r3)
48 blr
49
50/*
51 * Store VMX state into memory, including VSCR.
52 * Assumes the caller has enabled VMX in the MSR.
53 */
54_GLOBAL(store_vr_state)
55 SAVE_32VRS(0, r4, r3)
56 mfvscr vr0
57 li r4, VRSTATE_VSCR
58 stvx vr0, r4, r3
59 blr
60
61/*
63 * Disable VMX for the task which had it previously, 62 * Disable VMX for the task which had it previously,
64 * and save its vector registers in its thread_struct. 63 * and save its vector registers in its thread_struct.
65 * Enables the VMX for use in the kernel on return. 64 * Enables the VMX for use in the kernel on return.
@@ -90,10 +89,11 @@ _GLOBAL(load_up_altivec)
90 /* Save VMX state to last_task_used_altivec's THREAD struct */ 89 /* Save VMX state to last_task_used_altivec's THREAD struct */
91 toreal(r4) 90 toreal(r4)
92 addi r4,r4,THREAD 91 addi r4,r4,THREAD
93 SAVE_32VRS(0,r5,r4) 92 addi r7,r4,THREAD_VRSTATE
93 SAVE_32VRS(0,r5,r7)
94 mfvscr vr0 94 mfvscr vr0
95 li r10,THREAD_VSCR 95 li r10,VRSTATE_VSCR
96 stvx vr0,r10,r4 96 stvx vr0,r10,r7
97 /* Disable VMX for last_task_used_altivec */ 97 /* Disable VMX for last_task_used_altivec */
98 PPC_LL r5,PT_REGS(r4) 98 PPC_LL r5,PT_REGS(r4)
99 toreal(r5) 99 toreal(r5)
@@ -125,12 +125,13 @@ _GLOBAL(load_up_altivec)
125 oris r12,r12,MSR_VEC@h 125 oris r12,r12,MSR_VEC@h
126 std r12,_MSR(r1) 126 std r12,_MSR(r1)
127#endif 127#endif
128 addi r7,r5,THREAD_VRSTATE
128 li r4,1 129 li r4,1
129 li r10,THREAD_VSCR 130 li r10,VRSTATE_VSCR
130 stw r4,THREAD_USED_VR(r5) 131 stw r4,THREAD_USED_VR(r5)
131 lvx vr0,r10,r5 132 lvx vr0,r10,r7
132 mtvscr vr0 133 mtvscr vr0
133 REST_32VRS(0,r4,r5) 134 REST_32VRS(0,r4,r7)
134#ifndef CONFIG_SMP 135#ifndef CONFIG_SMP
135 /* Update last_task_used_altivec to 'current' */ 136 /* Update last_task_used_altivec to 'current' */
136 subi r4,r5,THREAD /* Back to 'current' */ 137 subi r4,r5,THREAD /* Back to 'current' */
@@ -165,12 +166,16 @@ _GLOBAL(giveup_altivec)
165 PPC_LCMPI 0,r3,0 166 PPC_LCMPI 0,r3,0
166 beqlr /* if no previous owner, done */ 167 beqlr /* if no previous owner, done */
167 addi r3,r3,THREAD /* want THREAD of task */ 168 addi r3,r3,THREAD /* want THREAD of task */
169 PPC_LL r7,THREAD_VRSAVEAREA(r3)
168 PPC_LL r5,PT_REGS(r3) 170 PPC_LL r5,PT_REGS(r3)
169 PPC_LCMPI 0,r5,0 171 PPC_LCMPI 0,r7,0
170 SAVE_32VRS(0,r4,r3) 172 bne 2f
173 addi r7,r3,THREAD_VRSTATE
1742: PPC_LCMPI 0,r5,0
175 SAVE_32VRS(0,r4,r7)
171 mfvscr vr0 176 mfvscr vr0
172 li r4,THREAD_VSCR 177 li r4,VRSTATE_VSCR
173 stvx vr0,r4,r3 178 stvx vr0,r4,r7
174 beq 1f 179 beq 1f
175 PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5) 180 PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
176#ifdef CONFIG_VSX 181#ifdef CONFIG_VSX
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index 27db1e665959..c0b48f96a91c 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -444,7 +444,7 @@ void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr)
444#ifdef CONFIG_VSX 444#ifdef CONFIG_VSX
445 u64 *vcpu_vsx = vcpu->arch.vsr; 445 u64 *vcpu_vsx = vcpu->arch.vsr;
446#endif 446#endif
447 u64 *thread_fpr = (u64*)t->fpr; 447 u64 *thread_fpr = &t->fp_state.fpr[0][0];
448 int i; 448 int i;
449 449
450 /* 450 /*
@@ -466,14 +466,14 @@ void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr)
466 /* 466 /*
467 * Note that on CPUs with VSX, giveup_fpu stores 467 * Note that on CPUs with VSX, giveup_fpu stores
468 * both the traditional FP registers and the added VSX 468 * both the traditional FP registers and the added VSX
469 * registers into thread.fpr[]. 469 * registers into thread.fp_state.fpr[].
470 */ 470 */
471 if (current->thread.regs->msr & MSR_FP) 471 if (current->thread.regs->msr & MSR_FP)
472 giveup_fpu(current); 472 giveup_fpu(current);
473 for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++) 473 for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++)
474 vcpu_fpr[i] = thread_fpr[get_fpr_index(i)]; 474 vcpu_fpr[i] = thread_fpr[get_fpr_index(i)];
475 475
476 vcpu->arch.fpscr = t->fpscr.val; 476 vcpu->arch.fpscr = t->fp_state.fpscr;
477 477
478#ifdef CONFIG_VSX 478#ifdef CONFIG_VSX
479 if (cpu_has_feature(CPU_FTR_VSX)) 479 if (cpu_has_feature(CPU_FTR_VSX))
@@ -486,8 +486,8 @@ void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr)
486 if (msr & MSR_VEC) { 486 if (msr & MSR_VEC) {
487 if (current->thread.regs->msr & MSR_VEC) 487 if (current->thread.regs->msr & MSR_VEC)
488 giveup_altivec(current); 488 giveup_altivec(current);
489 memcpy(vcpu->arch.vr, t->vr, sizeof(vcpu->arch.vr)); 489 memcpy(vcpu->arch.vr, t->vr_state.vr, sizeof(vcpu->arch.vr));
490 vcpu->arch.vscr = t->vscr; 490 vcpu->arch.vscr = t->vr_state.vscr;
491 } 491 }
492#endif 492#endif
493 493
@@ -539,7 +539,7 @@ static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr,
539#ifdef CONFIG_VSX 539#ifdef CONFIG_VSX
540 u64 *vcpu_vsx = vcpu->arch.vsr; 540 u64 *vcpu_vsx = vcpu->arch.vsr;
541#endif 541#endif
542 u64 *thread_fpr = (u64*)t->fpr; 542 u64 *thread_fpr = &t->fp_state.fpr[0][0];
543 int i; 543 int i;
544 544
545 /* When we have paired singles, we emulate in software */ 545 /* When we have paired singles, we emulate in software */
@@ -584,15 +584,15 @@ static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr,
584 for (i = 0; i < ARRAY_SIZE(vcpu->arch.vsr) / 2; i++) 584 for (i = 0; i < ARRAY_SIZE(vcpu->arch.vsr) / 2; i++)
585 thread_fpr[get_fpr_index(i) + 1] = vcpu_vsx[i]; 585 thread_fpr[get_fpr_index(i) + 1] = vcpu_vsx[i];
586#endif 586#endif
587 t->fpscr.val = vcpu->arch.fpscr; 587 t->fp_state.fpscr = vcpu->arch.fpscr;
588 t->fpexc_mode = 0; 588 t->fpexc_mode = 0;
589 kvmppc_load_up_fpu(); 589 kvmppc_load_up_fpu();
590 } 590 }
591 591
592 if (msr & MSR_VEC) { 592 if (msr & MSR_VEC) {
593#ifdef CONFIG_ALTIVEC 593#ifdef CONFIG_ALTIVEC
594 memcpy(t->vr, vcpu->arch.vr, sizeof(vcpu->arch.vr)); 594 memcpy(t->vr_state.vr, vcpu->arch.vr, sizeof(vcpu->arch.vr));
595 t->vscr = vcpu->arch.vscr; 595 t->vr_state.vscr = vcpu->arch.vscr;
596 t->vrsave = -1; 596 t->vrsave = -1;
597 kvmppc_load_up_altivec(); 597 kvmppc_load_up_altivec();
598#endif 598#endif
@@ -1116,12 +1116,10 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
1116int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) 1116int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
1117{ 1117{
1118 int ret; 1118 int ret;
1119 double fpr[32][TS_FPRWIDTH]; 1119 struct thread_fp_state fp;
1120 unsigned int fpscr;
1121 int fpexc_mode; 1120 int fpexc_mode;
1122#ifdef CONFIG_ALTIVEC 1121#ifdef CONFIG_ALTIVEC
1123 vector128 vr[32]; 1122 struct thread_vr_state vr;
1124 vector128 vscr;
1125 unsigned long uninitialized_var(vrsave); 1123 unsigned long uninitialized_var(vrsave);
1126 int used_vr; 1124 int used_vr;
1127#endif 1125#endif
@@ -1153,8 +1151,7 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
1153 /* Save FPU state in stack */ 1151 /* Save FPU state in stack */
1154 if (current->thread.regs->msr & MSR_FP) 1152 if (current->thread.regs->msr & MSR_FP)
1155 giveup_fpu(current); 1153 giveup_fpu(current);
1156 memcpy(fpr, current->thread.fpr, sizeof(current->thread.fpr)); 1154 fp = current->thread.fp_state;
1157 fpscr = current->thread.fpscr.val;
1158 fpexc_mode = current->thread.fpexc_mode; 1155 fpexc_mode = current->thread.fpexc_mode;
1159 1156
1160#ifdef CONFIG_ALTIVEC 1157#ifdef CONFIG_ALTIVEC
@@ -1163,8 +1160,7 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
1163 if (used_vr) { 1160 if (used_vr) {
1164 if (current->thread.regs->msr & MSR_VEC) 1161 if (current->thread.regs->msr & MSR_VEC)
1165 giveup_altivec(current); 1162 giveup_altivec(current);
1166 memcpy(vr, current->thread.vr, sizeof(current->thread.vr)); 1163 vr = current->thread.vr_state;
1167 vscr = current->thread.vscr;
1168 vrsave = current->thread.vrsave; 1164 vrsave = current->thread.vrsave;
1169 } 1165 }
1170#endif 1166#endif
@@ -1196,15 +1192,13 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
1196 current->thread.regs->msr = ext_msr; 1192 current->thread.regs->msr = ext_msr;
1197 1193
1198 /* Restore FPU/VSX state from stack */ 1194 /* Restore FPU/VSX state from stack */
1199 memcpy(current->thread.fpr, fpr, sizeof(current->thread.fpr)); 1195 current->thread.fp_state = fp;
1200 current->thread.fpscr.val = fpscr;
1201 current->thread.fpexc_mode = fpexc_mode; 1196 current->thread.fpexc_mode = fpexc_mode;
1202 1197
1203#ifdef CONFIG_ALTIVEC 1198#ifdef CONFIG_ALTIVEC
1204 /* Restore Altivec state from stack */ 1199 /* Restore Altivec state from stack */
1205 if (used_vr && current->thread.used_vr) { 1200 if (used_vr && current->thread.used_vr) {
1206 memcpy(current->thread.vr, vr, sizeof(current->thread.vr)); 1201 current->thread.vr_state = vr;
1207 current->thread.vscr = vscr;
1208 current->thread.vrsave = vrsave; 1202 current->thread.vrsave = vrsave;
1209 } 1203 }
1210 current->thread.used_vr = used_vr; 1204 current->thread.used_vr = used_vr;
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 17722d82f1d1..5133199f6cb7 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -656,9 +656,8 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
656{ 656{
657 int ret, s; 657 int ret, s;
658#ifdef CONFIG_PPC_FPU 658#ifdef CONFIG_PPC_FPU
659 unsigned int fpscr; 659 struct thread_fp_state fp;
660 int fpexc_mode; 660 int fpexc_mode;
661 u64 fpr[32];
662#endif 661#endif
663 662
664 if (!vcpu->arch.sane) { 663 if (!vcpu->arch.sane) {
@@ -677,13 +676,13 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
677#ifdef CONFIG_PPC_FPU 676#ifdef CONFIG_PPC_FPU
678 /* Save userspace FPU state in stack */ 677 /* Save userspace FPU state in stack */
679 enable_kernel_fp(); 678 enable_kernel_fp();
680 memcpy(fpr, current->thread.fpr, sizeof(current->thread.fpr)); 679 fp = current->thread.fp_state;
681 fpscr = current->thread.fpscr.val;
682 fpexc_mode = current->thread.fpexc_mode; 680 fpexc_mode = current->thread.fpexc_mode;
683 681
684 /* Restore guest FPU state to thread */ 682 /* Restore guest FPU state to thread */
685 memcpy(current->thread.fpr, vcpu->arch.fpr, sizeof(vcpu->arch.fpr)); 683 memcpy(current->thread.fp_state.fpr, vcpu->arch.fpr,
686 current->thread.fpscr.val = vcpu->arch.fpscr; 684 sizeof(vcpu->arch.fpr));
685 current->thread.fp_state.fpscr = vcpu->arch.fpscr;
687 686
688 /* 687 /*
689 * Since we can't trap on MSR_FP in GS-mode, we consider the guest 688 * Since we can't trap on MSR_FP in GS-mode, we consider the guest
@@ -709,12 +708,12 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
709 vcpu->fpu_active = 0; 708 vcpu->fpu_active = 0;
710 709
711 /* Save guest FPU state from thread */ 710 /* Save guest FPU state from thread */
712 memcpy(vcpu->arch.fpr, current->thread.fpr, sizeof(vcpu->arch.fpr)); 711 memcpy(vcpu->arch.fpr, current->thread.fp_state.fpr,
713 vcpu->arch.fpscr = current->thread.fpscr.val; 712 sizeof(vcpu->arch.fpr));
713 vcpu->arch.fpscr = current->thread.fp_state.fpscr;
714 714
715 /* Restore userspace FPU state from stack */ 715 /* Restore userspace FPU state from stack */
716 memcpy(current->thread.fpr, fpr, sizeof(current->thread.fpr)); 716 current->thread.fp_state = fp;
717 current->thread.fpscr.val = fpscr;
718 current->thread.fpexc_mode = fpexc_mode; 717 current->thread.fpexc_mode = fpexc_mode;
719#endif 718#endif
720 719
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index 8ed035d2edb5..e3734edffa69 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -304,5 +304,54 @@ void register_page_bootmem_memmap(unsigned long section_nr,
304 struct page *start_page, unsigned long size) 304 struct page *start_page, unsigned long size)
305{ 305{
306} 306}
307#endif /* CONFIG_SPARSEMEM_VMEMMAP */
308 307
308/*
309 * We do not have access to the sparsemem vmemmap, so we fallback to
310 * walking the list of sparsemem blocks which we already maintain for
311 * the sake of crashdump. In the long run, we might want to maintain
312 * a tree if performance of that linear walk becomes a problem.
313 *
314 * realmode_pfn_to_page functions can fail due to:
315 * 1) As real sparsemem blocks do not lay in RAM continously (they
316 * are in virtual address space which is not available in the real mode),
317 * the requested page struct can be split between blocks so get_page/put_page
318 * may fail.
319 * 2) When huge pages are used, the get_page/put_page API will fail
320 * in real mode as the linked addresses in the page struct are virtual
321 * too.
322 */
323struct page *realmode_pfn_to_page(unsigned long pfn)
324{
325 struct vmemmap_backing *vmem_back;
326 struct page *page;
327 unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift;
328 unsigned long pg_va = (unsigned long) pfn_to_page(pfn);
329
330 for (vmem_back = vmemmap_list; vmem_back; vmem_back = vmem_back->list) {
331 if (pg_va < vmem_back->virt_addr)
332 continue;
333
334 /* Check that page struct is not split between real pages */
335 if ((pg_va + sizeof(struct page)) >
336 (vmem_back->virt_addr + page_size))
337 return NULL;
338
339 page = (struct page *) (vmem_back->phys + pg_va -
340 vmem_back->virt_addr);
341 return page;
342 }
343
344 return NULL;
345}
346EXPORT_SYMBOL_GPL(realmode_pfn_to_page);
347
348#elif defined(CONFIG_FLATMEM)
349
350struct page *realmode_pfn_to_page(unsigned long pfn)
351{
352 struct page *page = pfn_to_page(pfn);
353 return page;
354}
355EXPORT_SYMBOL_GPL(realmode_pfn_to_page);
356
357#endif /* CONFIG_SPARSEMEM_VMEMMAP/CONFIG_FLATMEM */
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index a6531d2ff6c2..c639af7d4826 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -70,6 +70,16 @@ define_pe_printk_level(pe_err, KERN_ERR);
70define_pe_printk_level(pe_warn, KERN_WARNING); 70define_pe_printk_level(pe_warn, KERN_WARNING);
71define_pe_printk_level(pe_info, KERN_INFO); 71define_pe_printk_level(pe_info, KERN_INFO);
72 72
73/*
74 * stdcix is only supposed to be used in hypervisor real mode as per
75 * the architecture spec
76 */
77static inline void __raw_rm_writeq(u64 val, volatile void __iomem *paddr)
78{
79 __asm__ __volatile__("stdcix %0,0,%1"
80 : : "r" (val), "r" (paddr) : "memory");
81}
82
73static int pnv_ioda_alloc_pe(struct pnv_phb *phb) 83static int pnv_ioda_alloc_pe(struct pnv_phb *phb)
74{ 84{
75 unsigned long pe; 85 unsigned long pe;
@@ -454,10 +464,13 @@ static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe, struct pci_bus *bus)
454 } 464 }
455} 465}
456 466
457static void pnv_pci_ioda1_tce_invalidate(struct iommu_table *tbl, 467static void pnv_pci_ioda1_tce_invalidate(struct pnv_ioda_pe *pe,
458 __be64 *startp, __be64 *endp) 468 struct iommu_table *tbl,
469 __be64 *startp, __be64 *endp, bool rm)
459{ 470{
460 __be64 __iomem *invalidate = (__be64 __iomem *)tbl->it_index; 471 __be64 __iomem *invalidate = rm ?
472 (__be64 __iomem *)pe->tce_inval_reg_phys :
473 (__be64 __iomem *)tbl->it_index;
461 unsigned long start, end, inc; 474 unsigned long start, end, inc;
462 475
463 start = __pa(startp); 476 start = __pa(startp);
@@ -484,7 +497,10 @@ static void pnv_pci_ioda1_tce_invalidate(struct iommu_table *tbl,
484 497
485 mb(); /* Ensure above stores are visible */ 498 mb(); /* Ensure above stores are visible */
486 while (start <= end) { 499 while (start <= end) {
487 __raw_writeq(cpu_to_be64(start), invalidate); 500 if (rm)
501 __raw_rm_writeq(cpu_to_be64(start), invalidate);
502 else
503 __raw_writeq(cpu_to_be64(start), invalidate);
488 start += inc; 504 start += inc;
489 } 505 }
490 506
@@ -496,10 +512,12 @@ static void pnv_pci_ioda1_tce_invalidate(struct iommu_table *tbl,
496 512
497static void pnv_pci_ioda2_tce_invalidate(struct pnv_ioda_pe *pe, 513static void pnv_pci_ioda2_tce_invalidate(struct pnv_ioda_pe *pe,
498 struct iommu_table *tbl, 514 struct iommu_table *tbl,
499 __be64 *startp, __be64 *endp) 515 __be64 *startp, __be64 *endp, bool rm)
500{ 516{
501 unsigned long start, end, inc; 517 unsigned long start, end, inc;
502 __be64 __iomem *invalidate = (__be64 __iomem *)tbl->it_index; 518 __be64 __iomem *invalidate = rm ?
519 (__be64 __iomem *)pe->tce_inval_reg_phys :
520 (__be64 __iomem *)tbl->it_index;
503 521
504 /* We'll invalidate DMA address in PE scope */ 522 /* We'll invalidate DMA address in PE scope */
505 start = 0x2ul << 60; 523 start = 0x2ul << 60;
@@ -515,22 +533,25 @@ static void pnv_pci_ioda2_tce_invalidate(struct pnv_ioda_pe *pe,
515 mb(); 533 mb();
516 534
517 while (start <= end) { 535 while (start <= end) {
518 __raw_writeq(cpu_to_be64(start), invalidate); 536 if (rm)
537 __raw_rm_writeq(cpu_to_be64(start), invalidate);
538 else
539 __raw_writeq(cpu_to_be64(start), invalidate);
519 start += inc; 540 start += inc;
520 } 541 }
521} 542}
522 543
523void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl, 544void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl,
524 __be64 *startp, __be64 *endp) 545 __be64 *startp, __be64 *endp, bool rm)
525{ 546{
526 struct pnv_ioda_pe *pe = container_of(tbl, struct pnv_ioda_pe, 547 struct pnv_ioda_pe *pe = container_of(tbl, struct pnv_ioda_pe,
527 tce32_table); 548 tce32_table);
528 struct pnv_phb *phb = pe->phb; 549 struct pnv_phb *phb = pe->phb;
529 550
530 if (phb->type == PNV_PHB_IODA1) 551 if (phb->type == PNV_PHB_IODA1)
531 pnv_pci_ioda1_tce_invalidate(tbl, startp, endp); 552 pnv_pci_ioda1_tce_invalidate(pe, tbl, startp, endp, rm);
532 else 553 else
533 pnv_pci_ioda2_tce_invalidate(pe, tbl, startp, endp); 554 pnv_pci_ioda2_tce_invalidate(pe, tbl, startp, endp, rm);
534} 555}
535 556
536static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb, 557static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb,
@@ -603,7 +624,9 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb,
603 * bus number, print that out instead. 624 * bus number, print that out instead.
604 */ 625 */
605 tbl->it_busno = 0; 626 tbl->it_busno = 0;
606 tbl->it_index = (unsigned long)ioremap(be64_to_cpup(swinvp), 8); 627 pe->tce_inval_reg_phys = be64_to_cpup(swinvp);
628 tbl->it_index = (unsigned long)ioremap(pe->tce_inval_reg_phys,
629 8);
607 tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE | 630 tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE |
608 TCE_PCI_SWINV_PAIR; 631 TCE_PCI_SWINV_PAIR;
609 } 632 }
@@ -681,7 +704,9 @@ static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb,
681 * bus number, print that out instead. 704 * bus number, print that out instead.
682 */ 705 */
683 tbl->it_busno = 0; 706 tbl->it_busno = 0;
684 tbl->it_index = (unsigned long)ioremap(be64_to_cpup(swinvp), 8); 707 pe->tce_inval_reg_phys = be64_to_cpup(swinvp);
708 tbl->it_index = (unsigned long)ioremap(pe->tce_inval_reg_phys,
709 8);
685 tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE; 710 tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE;
686 } 711 }
687 iommu_init_table(tbl, phb->hose->node); 712 iommu_init_table(tbl, phb->hose->node);
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index a26956c5f38c..921ae673baf3 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -401,7 +401,7 @@ struct pci_ops pnv_pci_ops = {
401 401
402static int pnv_tce_build(struct iommu_table *tbl, long index, long npages, 402static int pnv_tce_build(struct iommu_table *tbl, long index, long npages,
403 unsigned long uaddr, enum dma_data_direction direction, 403 unsigned long uaddr, enum dma_data_direction direction,
404 struct dma_attrs *attrs) 404 struct dma_attrs *attrs, bool rm)
405{ 405{
406 u64 proto_tce; 406 u64 proto_tce;
407 __be64 *tcep, *tces; 407 __be64 *tcep, *tces;
@@ -423,12 +423,22 @@ static int pnv_tce_build(struct iommu_table *tbl, long index, long npages,
423 * of flags if that becomes the case 423 * of flags if that becomes the case
424 */ 424 */
425 if (tbl->it_type & TCE_PCI_SWINV_CREATE) 425 if (tbl->it_type & TCE_PCI_SWINV_CREATE)
426 pnv_pci_ioda_tce_invalidate(tbl, tces, tcep - 1); 426 pnv_pci_ioda_tce_invalidate(tbl, tces, tcep - 1, rm);
427 427
428 return 0; 428 return 0;
429} 429}
430 430
431static void pnv_tce_free(struct iommu_table *tbl, long index, long npages) 431static int pnv_tce_build_vm(struct iommu_table *tbl, long index, long npages,
432 unsigned long uaddr,
433 enum dma_data_direction direction,
434 struct dma_attrs *attrs)
435{
436 return pnv_tce_build(tbl, index, npages, uaddr, direction, attrs,
437 false);
438}
439
440static void pnv_tce_free(struct iommu_table *tbl, long index, long npages,
441 bool rm)
432{ 442{
433 __be64 *tcep, *tces; 443 __be64 *tcep, *tces;
434 444
@@ -438,7 +448,12 @@ static void pnv_tce_free(struct iommu_table *tbl, long index, long npages)
438 *(tcep++) = cpu_to_be64(0); 448 *(tcep++) = cpu_to_be64(0);
439 449
440 if (tbl->it_type & TCE_PCI_SWINV_FREE) 450 if (tbl->it_type & TCE_PCI_SWINV_FREE)
441 pnv_pci_ioda_tce_invalidate(tbl, tces, tcep - 1); 451 pnv_pci_ioda_tce_invalidate(tbl, tces, tcep - 1, rm);
452}
453
454static void pnv_tce_free_vm(struct iommu_table *tbl, long index, long npages)
455{
456 pnv_tce_free(tbl, index, npages, false);
442} 457}
443 458
444static unsigned long pnv_tce_get(struct iommu_table *tbl, long index) 459static unsigned long pnv_tce_get(struct iommu_table *tbl, long index)
@@ -446,6 +461,19 @@ static unsigned long pnv_tce_get(struct iommu_table *tbl, long index)
446 return ((u64 *)tbl->it_base)[index - tbl->it_offset]; 461 return ((u64 *)tbl->it_base)[index - tbl->it_offset];
447} 462}
448 463
464static int pnv_tce_build_rm(struct iommu_table *tbl, long index, long npages,
465 unsigned long uaddr,
466 enum dma_data_direction direction,
467 struct dma_attrs *attrs)
468{
469 return pnv_tce_build(tbl, index, npages, uaddr, direction, attrs, true);
470}
471
472static void pnv_tce_free_rm(struct iommu_table *tbl, long index, long npages)
473{
474 pnv_tce_free(tbl, index, npages, true);
475}
476
449void pnv_pci_setup_iommu_table(struct iommu_table *tbl, 477void pnv_pci_setup_iommu_table(struct iommu_table *tbl,
450 void *tce_mem, u64 tce_size, 478 void *tce_mem, u64 tce_size,
451 u64 dma_offset) 479 u64 dma_offset)
@@ -610,8 +638,10 @@ void __init pnv_pci_init(void)
610 638
611 /* Configure IOMMU DMA hooks */ 639 /* Configure IOMMU DMA hooks */
612 ppc_md.pci_dma_dev_setup = pnv_pci_dma_dev_setup; 640 ppc_md.pci_dma_dev_setup = pnv_pci_dma_dev_setup;
613 ppc_md.tce_build = pnv_tce_build; 641 ppc_md.tce_build = pnv_tce_build_vm;
614 ppc_md.tce_free = pnv_tce_free; 642 ppc_md.tce_free = pnv_tce_free_vm;
643 ppc_md.tce_build_rm = pnv_tce_build_rm;
644 ppc_md.tce_free_rm = pnv_tce_free_rm;
615 ppc_md.tce_get = pnv_tce_get; 645 ppc_md.tce_get = pnv_tce_get;
616 ppc_md.pci_probe_mode = pnv_pci_probe_mode; 646 ppc_md.pci_probe_mode = pnv_pci_probe_mode;
617 set_pci_dma_ops(&dma_iommu_ops); 647 set_pci_dma_ops(&dma_iommu_ops);
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h
index d0bb5204ece3..64d3b12e5b6d 100644
--- a/arch/powerpc/platforms/powernv/pci.h
+++ b/arch/powerpc/platforms/powernv/pci.h
@@ -52,6 +52,7 @@ struct pnv_ioda_pe {
52 int tce32_seg; 52 int tce32_seg;
53 int tce32_segcount; 53 int tce32_segcount;
54 struct iommu_table tce32_table; 54 struct iommu_table tce32_table;
55 phys_addr_t tce_inval_reg_phys;
55 56
56 /* XXX TODO: Add support for additional 64-bit iommus */ 57 /* XXX TODO: Add support for additional 64-bit iommus */
57 58
@@ -193,6 +194,6 @@ extern void pnv_pci_init_p5ioc2_hub(struct device_node *np);
193extern void pnv_pci_init_ioda_hub(struct device_node *np); 194extern void pnv_pci_init_ioda_hub(struct device_node *np);
194extern void pnv_pci_init_ioda2_phb(struct device_node *np); 195extern void pnv_pci_init_ioda2_phb(struct device_node *np);
195extern void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl, 196extern void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl,
196 __be64 *startp, __be64 *endp); 197 __be64 *startp, __be64 *endp, bool rm);
197 198
198#endif /* __POWERNV_PCI_H */ 199#endif /* __POWERNV_PCI_H */