[PATCH 5/6] s390: run user space and KVM guests with modified branch prediction

2018-02-06 Thread Martin Schwidefsky
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 
---
 arch/s390/include/asm/processor.h   |  3 +++
 arch/s390/include/asm/thread_info.h |  4 +++
 arch/s390/kernel/entry.S| 51 +
 arch/s390/kernel/processor.c| 18 +
 4 files changed, 71 insertions(+), 5 deletions(-)

diff --git a/arch/s390/include/asm/processor.h 
b/arch/s390/include/asm/processor.h
index 5f37f9c..7f2953c 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);
memcpy_absolute(&(dest), &__tmp, sizeof(__tmp));\
 } while (0)
 
+extern int s390_isolate_bp(void);
+extern int s390_isolate_bp_guest(void);
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __ASM_S390_PROCESSOR_H */
diff --git a/arch/s390/include/asm/thread_info.h 
b/arch/s390/include/asm/thread_info.h
index 25d6ec3..83ba575 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);
 #define TIF_GUARDED_STORAGE4   /* load guarded storage control block */
 #define TIF_PATCH_PENDING  5   /* pending live patching update */
 #define TIF_PGSTE  6   /* New mm's will use 4K page tables */
+#define TIF_ISOLATE_BP 8   /* Run process with isolated BP */
+#define TIF_ISOLATE_BP_GUEST   9   /* Run KVM guests with isolated BP */
 
 #define TIF_31BIT  16  /* 32bit process */
 #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);
 #define _TIF_UPROBE_BITUL(TIF_UPROBE)
 #define _TIF_GUARDED_STORAGE   _BITUL(TIF_GUARDED_STORAGE)
 #define _TIF_PATCH_PENDING _BITUL(TIF_PATCH_PENDING)
+#define _TIF_ISOLATE_BP_BITUL(TIF_ISOLATE_BP)
+#define _TIF_ISOLATE_BP_GUEST  _BITUL(TIF_ISOLATE_BP_GUEST)
 
 #define _TIF_31BIT _BITUL(TIF_31BIT)
 #define _TIF_SINGLE_STEP   _BITUL(TIF_SINGLE_STEP)
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index e6d7550..53145b5 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)
aghi%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
j   3f
 1: UPDATE_VTIME %r14,%r15,\timer
+   BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
 2: lg  %r15,__LC_ASYNC_STACK   # load async stack
 3: la  %r11,STACK_FRAME_OVERHEAD(%r15)
.endm
@@ -187,6 +188,40 @@ _PIF_WORK  = (_PIF_PER_TRAP | _PIF_SYSCALL_RESTART)
.popsection
.endm
 
+   .macro BPENTER tif_ptr,tif_mask
+   .pushsection .altinstr_replacement, "ax"
+662:   .word   0xc004, 0x, 0x  # 6 byte nop
+   .word   0xc004, 0x, 0x  # 6 byte nop
+   .popsection
+664:   TSTMSK  \tif_ptr,\tif_mask
+   jz  . + 8
+   .long   0xb2e8d000
+   .pushsection .altinstructions, "a"
+   .long 664b - .
+   .long 662b - .
+   .word 82
+   .byte 12
+   .byte 12
+   .popsection
+   .endm
+
+   .macro BPEXIT tif_ptr,tif_mask
+   TSTMSK  \tif_ptr,\tif_mask
+   .pushsection .altinstr_replacement, "ax"
+662:   jnz . + 8
+   .long   0xb2e8d000
+   .popsection
+664:   jz  . + 8
+   .long   0xb2e8c000
+   .pushsection .altinstructions, "a"
+   .long 664b - .
+   .long 662b - .
+   .word 82
+   .byte 8
+   .byte 8
+   .popsection
+   .endm
+
.section .kprobes.text, "ax"
 .Ldummy:
/*
@@ -240,9 +275,11 @@ ENTRY(__switch_to)
  */
 ENTRY(sie64a)
stmg%r6,%r14,__SF_GPRS(%r15)# save kernel registers
+   lg  %r12,__LC_CURRENT
stg %r2,__SF_EMPTY(%r15)# save control block pointer
stg %r3,__SF_EMPTY+8(%r15)  # save guest register save area
xc  __SF_EMPTY+16(8,%r15),__SF_EMPTY+16(%r15) # reason code = 0
+   mvc __SF_EMPTY+24(8,%r15),__TI_flags(%r12) # copy thread flags
TSTMSK  __LC_CPU_FLAGS,_CIF_FPU # load guest fp/vx registers ?
jno .Lsie_load_guest_gprs
brasl   %r14,load_fpu_regs  # load guest fp/vx regs
@@ -259,11 +296,12 @@ ENTRY(sie64a)
jnz .Lsie_skip
TSTMSK  __LC_CPU_FLAGS,_CIF_FPU
jo  .Lsie_skip  # exit if fp/vx regs changed
-   BPON
+   

[PATCH 5/6] s390: run user space and KVM guests with modified branch prediction

2018-02-06 Thread Martin Schwidefsky
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 
---
 arch/s390/include/asm/processor.h   |  3 +++
 arch/s390/include/asm/thread_info.h |  4 +++
 arch/s390/kernel/entry.S| 51 +
 arch/s390/kernel/processor.c| 18 +
 4 files changed, 71 insertions(+), 5 deletions(-)

diff --git a/arch/s390/include/asm/processor.h 
b/arch/s390/include/asm/processor.h
index 5f37f9c..7f2953c 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);
memcpy_absolute(&(dest), &__tmp, sizeof(__tmp));\
 } while (0)
 
+extern int s390_isolate_bp(void);
+extern int s390_isolate_bp_guest(void);
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __ASM_S390_PROCESSOR_H */
diff --git a/arch/s390/include/asm/thread_info.h 
b/arch/s390/include/asm/thread_info.h
index 25d6ec3..83ba575 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);
 #define TIF_GUARDED_STORAGE4   /* load guarded storage control block */
 #define TIF_PATCH_PENDING  5   /* pending live patching update */
 #define TIF_PGSTE  6   /* New mm's will use 4K page tables */
+#define TIF_ISOLATE_BP 8   /* Run process with isolated BP */
+#define TIF_ISOLATE_BP_GUEST   9   /* Run KVM guests with isolated BP */
 
 #define TIF_31BIT  16  /* 32bit process */
 #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);
 #define _TIF_UPROBE_BITUL(TIF_UPROBE)
 #define _TIF_GUARDED_STORAGE   _BITUL(TIF_GUARDED_STORAGE)
 #define _TIF_PATCH_PENDING _BITUL(TIF_PATCH_PENDING)
+#define _TIF_ISOLATE_BP_BITUL(TIF_ISOLATE_BP)
+#define _TIF_ISOLATE_BP_GUEST  _BITUL(TIF_ISOLATE_BP_GUEST)
 
 #define _TIF_31BIT _BITUL(TIF_31BIT)
 #define _TIF_SINGLE_STEP   _BITUL(TIF_SINGLE_STEP)
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index e6d7550..53145b5 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)
aghi%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
j   3f
 1: UPDATE_VTIME %r14,%r15,\timer
+   BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
 2: lg  %r15,__LC_ASYNC_STACK   # load async stack
 3: la  %r11,STACK_FRAME_OVERHEAD(%r15)
.endm
@@ -187,6 +188,40 @@ _PIF_WORK  = (_PIF_PER_TRAP | _PIF_SYSCALL_RESTART)
.popsection
.endm
 
+   .macro BPENTER tif_ptr,tif_mask
+   .pushsection .altinstr_replacement, "ax"
+662:   .word   0xc004, 0x, 0x  # 6 byte nop
+   .word   0xc004, 0x, 0x  # 6 byte nop
+   .popsection
+664:   TSTMSK  \tif_ptr,\tif_mask
+   jz  . + 8
+   .long   0xb2e8d000
+   .pushsection .altinstructions, "a"
+   .long 664b - .
+   .long 662b - .
+   .word 82
+   .byte 12
+   .byte 12
+   .popsection
+   .endm
+
+   .macro BPEXIT tif_ptr,tif_mask
+   TSTMSK  \tif_ptr,\tif_mask
+   .pushsection .altinstr_replacement, "ax"
+662:   jnz . + 8
+   .long   0xb2e8d000
+   .popsection
+664:   jz  . + 8
+   .long   0xb2e8c000
+   .pushsection .altinstructions, "a"
+   .long 664b - .
+   .long 662b - .
+   .word 82
+   .byte 8
+   .byte 8
+   .popsection
+   .endm
+
.section .kprobes.text, "ax"
 .Ldummy:
/*
@@ -240,9 +275,11 @@ ENTRY(__switch_to)
  */
 ENTRY(sie64a)
stmg%r6,%r14,__SF_GPRS(%r15)# save kernel registers
+   lg  %r12,__LC_CURRENT
stg %r2,__SF_EMPTY(%r15)# save control block pointer
stg %r3,__SF_EMPTY+8(%r15)  # save guest register save area
xc  __SF_EMPTY+16(8,%r15),__SF_EMPTY+16(%r15) # reason code = 0
+   mvc __SF_EMPTY+24(8,%r15),__TI_flags(%r12) # copy thread flags
TSTMSK  __LC_CPU_FLAGS,_CIF_FPU # load guest fp/vx registers ?
jno .Lsie_load_guest_gprs
brasl   %r14,load_fpu_regs  # load guest fp/vx regs
@@ -259,11 +296,12 @@ ENTRY(sie64a)
jnz .Lsie_skip
TSTMSK  __LC_CPU_FLAGS,_CIF_FPU
jo  .Lsie_skip  # exit if fp/vx regs changed
-   BPON
+   BPEXIT