summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2018-01-16 01:36:46 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2018-02-05 08:48:50 -0500
commit6b73044b2b0081ee3dd1cd6eaab7dee552601efb (patch)
tree25a142770f34cb0b7ba27e691d02509902a1974d
parentd768bd892fc8f066cd3aa000eb1867bcf32db0ee (diff)
s390: run user space and KVM guests with modified branch prediction
Define TIF_ISOLATE_BP and TIF_ISOLATE_BP_GUEST and add the necessary plumbing in entry.S to be able to run user space and KVM guests with limited branch prediction. To switch a user space process to limited branch prediction the s390_isolate_bp() function has to be call, and to run a vCPU of a KVM guest associated with the current task with limited branch prediction call s390_isolate_bp_guest(). Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--arch/s390/include/asm/processor.h3
-rw-r--r--arch/s390/include/asm/thread_info.h4
-rw-r--r--arch/s390/kernel/entry.S51
-rw-r--r--arch/s390/kernel/processor.c18
4 files changed, 71 insertions, 5 deletions
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
index 5f37f9ceef5e..7f2953c15c37 100644
--- a/arch/s390/include/asm/processor.h
+++ b/arch/s390/include/asm/processor.h
@@ -378,6 +378,9 @@ extern void memcpy_absolute(void *, void *, size_t);
378 memcpy_absolute(&(dest), &__tmp, sizeof(__tmp)); \ 378 memcpy_absolute(&(dest), &__tmp, sizeof(__tmp)); \
379} while (0) 379} while (0)
380 380
381extern int s390_isolate_bp(void);
382extern int s390_isolate_bp_guest(void);
383
381#endif /* __ASSEMBLY__ */ 384#endif /* __ASSEMBLY__ */
382 385
383#endif /* __ASM_S390_PROCESSOR_H */ 386#endif /* __ASM_S390_PROCESSOR_H */
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h
index 25d6ec3aaddd..83ba57533ce6 100644
--- a/arch/s390/include/asm/thread_info.h
+++ b/arch/s390/include/asm/thread_info.h
@@ -58,6 +58,8 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
58#define TIF_GUARDED_STORAGE 4 /* load guarded storage control block */ 58#define TIF_GUARDED_STORAGE 4 /* load guarded storage control block */
59#define TIF_PATCH_PENDING 5 /* pending live patching update */ 59#define TIF_PATCH_PENDING 5 /* pending live patching update */
60#define TIF_PGSTE 6 /* New mm's will use 4K page tables */ 60#define TIF_PGSTE 6 /* New mm's will use 4K page tables */
61#define TIF_ISOLATE_BP 8 /* Run process with isolated BP */
62#define TIF_ISOLATE_BP_GUEST 9 /* Run KVM guests with isolated BP */
61 63
62#define TIF_31BIT 16 /* 32bit process */ 64#define TIF_31BIT 16 /* 32bit process */
63#define TIF_MEMDIE 17 /* is terminating due to OOM killer */ 65#define TIF_MEMDIE 17 /* is terminating due to OOM killer */
@@ -78,6 +80,8 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
78#define _TIF_UPROBE _BITUL(TIF_UPROBE) 80#define _TIF_UPROBE _BITUL(TIF_UPROBE)
79#define _TIF_GUARDED_STORAGE _BITUL(TIF_GUARDED_STORAGE) 81#define _TIF_GUARDED_STORAGE _BITUL(TIF_GUARDED_STORAGE)
80#define _TIF_PATCH_PENDING _BITUL(TIF_PATCH_PENDING) 82#define _TIF_PATCH_PENDING _BITUL(TIF_PATCH_PENDING)
83#define _TIF_ISOLATE_BP _BITUL(TIF_ISOLATE_BP)
84#define _TIF_ISOLATE_BP_GUEST _BITUL(TIF_ISOLATE_BP_GUEST)
81 85
82#define _TIF_31BIT _BITUL(TIF_31BIT) 86#define _TIF_31BIT _BITUL(TIF_31BIT)
83#define _TIF_SINGLE_STEP _BITUL(TIF_SINGLE_STEP) 87#define _TIF_SINGLE_STEP _BITUL(TIF_SINGLE_STEP)
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index e6d7550a3af8..53145b5d987d 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -107,6 +107,7 @@ _PIF_WORK = (_PIF_PER_TRAP | _PIF_SYSCALL_RESTART)
107 aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) 107 aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
108 j 3f 108 j 3f
1091: UPDATE_VTIME %r14,%r15,\timer 1091: UPDATE_VTIME %r14,%r15,\timer
110 BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
1102: lg %r15,__LC_ASYNC_STACK # load async stack 1112: lg %r15,__LC_ASYNC_STACK # load async stack
1113: la %r11,STACK_FRAME_OVERHEAD(%r15) 1123: la %r11,STACK_FRAME_OVERHEAD(%r15)
112 .endm 113 .endm
@@ -187,6 +188,40 @@ _PIF_WORK = (_PIF_PER_TRAP | _PIF_SYSCALL_RESTART)
187 .popsection 188 .popsection
188 .endm 189 .endm
189 190
191 .macro BPENTER tif_ptr,tif_mask
192 .pushsection .altinstr_replacement, "ax"
193662: .word 0xc004, 0x0000, 0x0000 # 6 byte nop
194 .word 0xc004, 0x0000, 0x0000 # 6 byte nop
195 .popsection
196664: TSTMSK \tif_ptr,\tif_mask
197 jz . + 8
198 .long 0xb2e8d000
199 .pushsection .altinstructions, "a"
200 .long 664b - .
201 .long 662b - .
202 .word 82
203 .byte 12
204 .byte 12
205 .popsection
206 .endm
207
208 .macro BPEXIT tif_ptr,tif_mask
209 TSTMSK \tif_ptr,\tif_mask
210 .pushsection .altinstr_replacement, "ax"
211662: jnz . + 8
212 .long 0xb2e8d000
213 .popsection
214664: jz . + 8
215 .long 0xb2e8c000
216 .pushsection .altinstructions, "a"
217 .long 664b - .
218 .long 662b - .
219 .word 82
220 .byte 8
221 .byte 8
222 .popsection
223 .endm
224
190 .section .kprobes.text, "ax" 225 .section .kprobes.text, "ax"
191.Ldummy: 226.Ldummy:
192 /* 227 /*
@@ -240,9 +275,11 @@ ENTRY(__switch_to)
240 */ 275 */
241ENTRY(sie64a) 276ENTRY(sie64a)
242 stmg %r6,%r14,__SF_GPRS(%r15) # save kernel registers 277 stmg %r6,%r14,__SF_GPRS(%r15) # save kernel registers
278 lg %r12,__LC_CURRENT
243 stg %r2,__SF_EMPTY(%r15) # save control block pointer 279 stg %r2,__SF_EMPTY(%r15) # save control block pointer
244 stg %r3,__SF_EMPTY+8(%r15) # save guest register save area 280 stg %r3,__SF_EMPTY+8(%r15) # save guest register save area
245 xc __SF_EMPTY+16(8,%r15),__SF_EMPTY+16(%r15) # reason code = 0 281 xc __SF_EMPTY+16(8,%r15),__SF_EMPTY+16(%r15) # reason code = 0
282 mvc __SF_EMPTY+24(8,%r15),__TI_flags(%r12) # copy thread flags
246 TSTMSK __LC_CPU_FLAGS,_CIF_FPU # load guest fp/vx registers ? 283 TSTMSK __LC_CPU_FLAGS,_CIF_FPU # load guest fp/vx registers ?
247 jno .Lsie_load_guest_gprs 284 jno .Lsie_load_guest_gprs
248 brasl %r14,load_fpu_regs # load guest fp/vx regs 285 brasl %r14,load_fpu_regs # load guest fp/vx regs
@@ -259,11 +296,12 @@ ENTRY(sie64a)
259 jnz .Lsie_skip 296 jnz .Lsie_skip
260 TSTMSK __LC_CPU_FLAGS,_CIF_FPU 297 TSTMSK __LC_CPU_FLAGS,_CIF_FPU
261 jo .Lsie_skip # exit if fp/vx regs changed 298 jo .Lsie_skip # exit if fp/vx regs changed
262 BPON 299 BPEXIT __SF_EMPTY+24(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
263.Lsie_entry: 300.Lsie_entry:
264 sie 0(%r14) 301 sie 0(%r14)
265.Lsie_exit: 302.Lsie_exit:
266 BPOFF 303 BPOFF
304 BPENTER __SF_EMPTY+24(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
267.Lsie_skip: 305.Lsie_skip:
268 ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE 306 ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE
269 lctlg %c1,%c1,__LC_USER_ASCE # load primary asce 307 lctlg %c1,%c1,__LC_USER_ASCE # load primary asce
@@ -324,6 +362,7 @@ ENTRY(system_call)
324 la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs 362 la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs
325.Lsysc_vtime: 363.Lsysc_vtime:
326 UPDATE_VTIME %r8,%r9,__LC_SYNC_ENTER_TIMER 364 UPDATE_VTIME %r8,%r9,__LC_SYNC_ENTER_TIMER
365 BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
327 stmg %r0,%r7,__PT_R0(%r11) 366 stmg %r0,%r7,__PT_R0(%r11)
328 # clear user controlled register to prevent speculative use 367 # clear user controlled register to prevent speculative use
329 xgr %r0,%r0 368 xgr %r0,%r0
@@ -362,7 +401,7 @@ ENTRY(system_call)
362 jnz .Lsysc_work # check for work 401 jnz .Lsysc_work # check for work
363 TSTMSK __LC_CPU_FLAGS,_CIF_WORK 402 TSTMSK __LC_CPU_FLAGS,_CIF_WORK
364 jnz .Lsysc_work 403 jnz .Lsysc_work
365 BPON 404 BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP
366.Lsysc_restore: 405.Lsysc_restore:
367 lg %r14,__LC_VDSO_PER_CPU 406 lg %r14,__LC_VDSO_PER_CPU
368 lmg %r0,%r10,__PT_R0(%r11) 407 lmg %r0,%r10,__PT_R0(%r11)
@@ -597,6 +636,7 @@ ENTRY(pgm_check_handler)
597 aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) 636 aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
598 j 4f 637 j 4f
5992: UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER 6382: UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER
639 BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
600 lg %r15,__LC_KERNEL_STACK 640 lg %r15,__LC_KERNEL_STACK
601 lgr %r14,%r12 641 lgr %r14,%r12
602 aghi %r14,__TASK_thread # pointer to thread_struct 642 aghi %r14,__TASK_thread # pointer to thread_struct
@@ -729,7 +769,7 @@ ENTRY(io_int_handler)
729 mvc __LC_RETURN_PSW(16),__PT_PSW(%r11) 769 mvc __LC_RETURN_PSW(16),__PT_PSW(%r11)
730 tm __PT_PSW+1(%r11),0x01 # returning to user ? 770 tm __PT_PSW+1(%r11),0x01 # returning to user ?
731 jno .Lio_exit_kernel 771 jno .Lio_exit_kernel
732 BPON 772 BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP
733.Lio_exit_timer: 773.Lio_exit_timer:
734 stpt __LC_EXIT_TIMER 774 stpt __LC_EXIT_TIMER
735 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER 775 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
@@ -1165,7 +1205,7 @@ ENTRY(mcck_int_handler)
1165 mvc __LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW 1205 mvc __LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW
1166 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? 1206 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
1167 jno 0f 1207 jno 0f
1168 BPON 1208 BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP
1169 stpt __LC_EXIT_TIMER 1209 stpt __LC_EXIT_TIMER
1170 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER 1210 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
11710: lmg %r11,%r15,__PT_R11(%r11) 12110: lmg %r11,%r15,__PT_R11(%r11)
@@ -1292,7 +1332,8 @@ cleanup_critical:
1292 clg %r9,BASED(.Lsie_crit_mcck_length) 1332 clg %r9,BASED(.Lsie_crit_mcck_length)
1293 jh 1f 1333 jh 1f
1294 oi __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST 1334 oi __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST
12951: lg %r9,__SF_EMPTY(%r15) # get control block pointer 13351: BPENTER __SF_EMPTY+24(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
1336 lg %r9,__SF_EMPTY(%r15) # get control block pointer
1296 ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE 1337 ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE
1297 lctlg %c1,%c1,__LC_USER_ASCE # load primary asce 1338 lctlg %c1,%c1,__LC_USER_ASCE # load primary asce
1298 larl %r9,sie_exit # skip forward to sie_exit 1339 larl %r9,sie_exit # skip forward to sie_exit
diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c
index 5362fd868d0d..6fe2e1875058 100644
--- a/arch/s390/kernel/processor.c
+++ b/arch/s390/kernel/processor.c
@@ -197,3 +197,21 @@ const struct seq_operations cpuinfo_op = {
197 .stop = c_stop, 197 .stop = c_stop,
198 .show = show_cpuinfo, 198 .show = show_cpuinfo,
199}; 199};
200
201int s390_isolate_bp(void)
202{
203 if (!test_facility(82))
204 return -EOPNOTSUPP;
205 set_thread_flag(TIF_ISOLATE_BP);
206 return 0;
207}
208EXPORT_SYMBOL(s390_isolate_bp);
209
210int s390_isolate_bp_guest(void)
211{
212 if (!test_facility(82))
213 return -EOPNOTSUPP;
214 set_thread_flag(TIF_ISOLATE_BP_GUEST);
215 return 0;
216}
217EXPORT_SYMBOL(s390_isolate_bp_guest);