aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorChristian Borntraeger <borntraeger@de.ibm.com>2013-05-17 08:41:34 -0400
committerGleb Natapov <gleb@redhat.com>2013-05-21 04:55:21 -0400
commit95d38fd0bcf1996082f5f8762e6f1c849755e0c6 (patch)
tree6693f983fc518ac46c6c5fd31ca15891fedfd97f /arch/s390
parent0d0dafc1e48fd254c22f75738def870a7ffd2c3e (diff)
s390/kvm: Mark if a cpu is in SIE
Lets track in a private bit if the sie control block is active. We want to track this as closely as possible, so we also have to instrument the interrupt and program check handler. Lets use the existing HANDLE_SIE_INTERCEPT macro. Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> Acked-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Gleb Natapov <gleb@redhat.com>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/include/asm/kvm_host.h5
-rw-r--r--arch/s390/kernel/asm-offsets.c2
-rw-r--r--arch/s390/kernel/entry64.S10
3 files changed, 13 insertions, 4 deletions
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index 16bd5d169cdb..962b92e6cf00 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -68,7 +68,10 @@ struct sca_block {
68struct kvm_s390_sie_block { 68struct kvm_s390_sie_block {
69 atomic_t cpuflags; /* 0x0000 */ 69 atomic_t cpuflags; /* 0x0000 */
70 __u32 prefix; /* 0x0004 */ 70 __u32 prefix; /* 0x0004 */
71 __u8 reserved8[32]; /* 0x0008 */ 71 __u8 reserved08[4]; /* 0x0008 */
72#define PROG_IN_SIE (1<<0)
73 __u32 prog0c; /* 0x000c */
74 __u8 reserved10[24]; /* 0x0010 */
72 __u64 cputm; /* 0x0028 */ 75 __u64 cputm; /* 0x0028 */
73 __u64 ckc; /* 0x0030 */ 76 __u64 ckc; /* 0x0030 */
74 __u64 epoch; /* 0x0038 */ 77 __u64 epoch; /* 0x0038 */
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c
index 7a82f9f70100..6456bbe1fbb1 100644
--- a/arch/s390/kernel/asm-offsets.c
+++ b/arch/s390/kernel/asm-offsets.c
@@ -7,6 +7,7 @@
7#define ASM_OFFSETS_C 7#define ASM_OFFSETS_C
8 8
9#include <linux/kbuild.h> 9#include <linux/kbuild.h>
10#include <linux/kvm_host.h>
10#include <linux/sched.h> 11#include <linux/sched.h>
11#include <asm/cputime.h> 12#include <asm/cputime.h>
12#include <asm/vdso.h> 13#include <asm/vdso.h>
@@ -161,6 +162,7 @@ int main(void)
161 DEFINE(__LC_PGM_TDB, offsetof(struct _lowcore, pgm_tdb)); 162 DEFINE(__LC_PGM_TDB, offsetof(struct _lowcore, pgm_tdb));
162 DEFINE(__THREAD_trap_tdb, offsetof(struct task_struct, thread.trap_tdb)); 163 DEFINE(__THREAD_trap_tdb, offsetof(struct task_struct, thread.trap_tdb));
163 DEFINE(__GMAP_ASCE, offsetof(struct gmap, asce)); 164 DEFINE(__GMAP_ASCE, offsetof(struct gmap, asce));
165 DEFINE(__SIE_PROG0C, offsetof(struct kvm_s390_sie_block, prog0c));
164#endif /* CONFIG_32BIT */ 166#endif /* CONFIG_32BIT */
165 return 0; 167 return 0;
166} 168}
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 4c17eece707e..c2e81b4ea42c 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -84,7 +84,7 @@ _TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING)
84 .macro HANDLE_SIE_INTERCEPT scratch,pgmcheck 84 .macro HANDLE_SIE_INTERCEPT scratch,pgmcheck
85#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) 85#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
86 tmhh %r8,0x0001 # interrupting from user ? 86 tmhh %r8,0x0001 # interrupting from user ?
87 jnz .+42 87 jnz .+52
88 lgr \scratch,%r9 88 lgr \scratch,%r9
89 slg \scratch,BASED(.Lsie_loop) 89 slg \scratch,BASED(.Lsie_loop)
90 clg \scratch,BASED(.Lsie_length) 90 clg \scratch,BASED(.Lsie_length)
@@ -92,12 +92,14 @@ _TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING)
92 # Some program interrupts are suppressing (e.g. protection). 92 # Some program interrupts are suppressing (e.g. protection).
93 # We must also check the instruction after SIE in that case. 93 # We must also check the instruction after SIE in that case.
94 # do_protection_exception will rewind to rewind_pad 94 # do_protection_exception will rewind to rewind_pad
95 jh .+22 95 jh .+32
96 .else 96 .else
97 jhe .+22 97 jhe .+32
98 .endif 98 .endif
99 lg %r9,BASED(.Lsie_loop) 99 lg %r9,BASED(.Lsie_loop)
100 LPP BASED(.Lhost_id) # set host id 100 LPP BASED(.Lhost_id) # set host id
101 lg %r14,__SF_EMPTY(%r15) # get control block pointer
102 ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE
101#endif 103#endif
102 .endm 104 .endm
103 105
@@ -956,10 +958,12 @@ sie_loop:
956 lctlg %c1,%c1,__GMAP_ASCE(%r14) # load primary asce 958 lctlg %c1,%c1,__GMAP_ASCE(%r14) # load primary asce
957sie_gmap: 959sie_gmap:
958 lg %r14,__SF_EMPTY(%r15) # get control block pointer 960 lg %r14,__SF_EMPTY(%r15) # get control block pointer
961 oi __SIE_PROG0C+3(%r14),1 # we are in SIE now
959 LPP __SF_EMPTY(%r15) # set guest id 962 LPP __SF_EMPTY(%r15) # set guest id
960 sie 0(%r14) 963 sie 0(%r14)
961sie_done: 964sie_done:
962 LPP __SF_EMPTY+16(%r15) # set host id 965 LPP __SF_EMPTY+16(%r15) # set host id
966 ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE
963 lg %r14,__LC_THREAD_INFO # pointer thread_info struct 967 lg %r14,__LC_THREAD_INFO # pointer thread_info struct
964sie_exit: 968sie_exit:
965 lctlg %c1,%c1,__LC_USER_ASCE # load primary asce 969 lctlg %c1,%c1,__LC_USER_ASCE # load primary asce