diff options
author | Christian Borntraeger <borntraeger@de.ibm.com> | 2013-05-17 08:41:34 -0400 |
---|---|---|
committer | Gleb Natapov <gleb@redhat.com> | 2013-05-21 04:55:21 -0400 |
commit | 95d38fd0bcf1996082f5f8762e6f1c849755e0c6 (patch) | |
tree | 6693f983fc518ac46c6c5fd31ca15891fedfd97f /arch/s390 | |
parent | 0d0dafc1e48fd254c22f75738def870a7ffd2c3e (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.h | 5 | ||||
-rw-r--r-- | arch/s390/kernel/asm-offsets.c | 2 | ||||
-rw-r--r-- | arch/s390/kernel/entry64.S | 10 |
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 { | |||
68 | struct kvm_s390_sie_block { | 68 | struct 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 |
957 | sie_gmap: | 959 | sie_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) |
961 | sie_done: | 964 | sie_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 |
964 | sie_exit: | 968 | sie_exit: |
965 | lctlg %c1,%c1,__LC_USER_ASCE # load primary asce | 969 | lctlg %c1,%c1,__LC_USER_ASCE # load primary asce |