aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Hildenbrand <dahi@linux.vnet.ibm.com>2014-03-03 04:54:33 -0500
committerChristian Borntraeger <borntraeger@de.ibm.com>2014-04-22 07:24:49 -0400
commit439716a5cab30e930bd1ec0f8fd66cbbaa319250 (patch)
treefcdfac184a376335cd2535c96fc4ad2fa3aa903a
parentda7cf2570c5fa29a02a3e8026bfff89620706d2f (diff)
KVM: s390: extract irq parameters of intercepted program irqs
Whenever a program interrupt is intercepted, some parameters are stored in the sie control block. These parameters have to be extracted in order to be reinjected correctly. This patch also takes care of intercepted PER events which can occurr in addition to any program interrupt. Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
-rw-r--r--arch/s390/include/asm/kvm_host.h18
-rw-r--r--arch/s390/kvm/intercept.c65
2 files changed, 79 insertions, 4 deletions
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index f1ed7bdba733..b8c808192893 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -120,9 +120,21 @@ struct kvm_s390_sie_block {
120 psw_t gpsw; /* 0x0090 */ 120 psw_t gpsw; /* 0x0090 */
121 __u64 gg14; /* 0x00a0 */ 121 __u64 gg14; /* 0x00a0 */
122 __u64 gg15; /* 0x00a8 */ 122 __u64 gg15; /* 0x00a8 */
123 __u8 reservedb0[30]; /* 0x00b0 */ 123 __u8 reservedb0[28]; /* 0x00b0 */
124 __u16 iprcc; /* 0x00ce */ 124 __u16 pgmilc; /* 0x00cc */
125 __u8 reservedd0[48]; /* 0x00d0 */ 125 __u16 iprcc; /* 0x00ce */
126 __u32 dxc; /* 0x00d0 */
127 __u16 mcn; /* 0x00d4 */
128 __u8 perc; /* 0x00d6 */
129 __u8 peratmid; /* 0x00d7 */
130 __u64 peraddr; /* 0x00d8 */
131 __u8 eai; /* 0x00e0 */
132 __u8 peraid; /* 0x00e1 */
133 __u8 oai; /* 0x00e2 */
134 __u8 armid; /* 0x00e3 */
135 __u8 reservede4[4]; /* 0x00e4 */
136 __u64 tecmc; /* 0x00e8 */
137 __u8 reservedf0[16]; /* 0x00f0 */
126 __u64 gcr[16]; /* 0x0100 */ 138 __u64 gcr[16]; /* 0x0100 */
127 __u64 gbea; /* 0x0180 */ 139 __u64 gbea; /* 0x0180 */
128 __u8 reserved188[24]; /* 0x0188 */ 140 __u8 reserved188[24]; /* 0x0188 */
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
index a8d8da84005b..4c3311e41727 100644
--- a/arch/s390/kvm/intercept.c
+++ b/arch/s390/kvm/intercept.c
@@ -109,8 +109,69 @@ static int handle_instruction(struct kvm_vcpu *vcpu)
109 return -EOPNOTSUPP; 109 return -EOPNOTSUPP;
110} 110}
111 111
112static void __extract_prog_irq(struct kvm_vcpu *vcpu,
113 struct kvm_s390_pgm_info *pgm_info)
114{
115 memset(pgm_info, 0, sizeof(struct kvm_s390_pgm_info));
116 pgm_info->code = vcpu->arch.sie_block->iprcc;
117
118 switch (vcpu->arch.sie_block->iprcc & ~PGM_PER) {
119 case PGM_AFX_TRANSLATION:
120 case PGM_ASX_TRANSLATION:
121 case PGM_EX_TRANSLATION:
122 case PGM_LFX_TRANSLATION:
123 case PGM_LSTE_SEQUENCE:
124 case PGM_LSX_TRANSLATION:
125 case PGM_LX_TRANSLATION:
126 case PGM_PRIMARY_AUTHORITY:
127 case PGM_SECONDARY_AUTHORITY:
128 case PGM_SPACE_SWITCH:
129 pgm_info->trans_exc_code = vcpu->arch.sie_block->tecmc;
130 break;
131 case PGM_ALEN_TRANSLATION:
132 case PGM_ALE_SEQUENCE:
133 case PGM_ASTE_INSTANCE:
134 case PGM_ASTE_SEQUENCE:
135 case PGM_ASTE_VALIDITY:
136 case PGM_EXTENDED_AUTHORITY:
137 pgm_info->exc_access_id = vcpu->arch.sie_block->eai;
138 break;
139 case PGM_ASCE_TYPE:
140 case PGM_PAGE_TRANSLATION:
141 case PGM_REGION_FIRST_TRANS:
142 case PGM_REGION_SECOND_TRANS:
143 case PGM_REGION_THIRD_TRANS:
144 case PGM_SEGMENT_TRANSLATION:
145 pgm_info->trans_exc_code = vcpu->arch.sie_block->tecmc;
146 pgm_info->exc_access_id = vcpu->arch.sie_block->eai;
147 pgm_info->op_access_id = vcpu->arch.sie_block->oai;
148 break;
149 case PGM_MONITOR:
150 pgm_info->mon_class_nr = vcpu->arch.sie_block->mcn;
151 pgm_info->mon_code = vcpu->arch.sie_block->tecmc;
152 break;
153 case PGM_DATA:
154 pgm_info->data_exc_code = vcpu->arch.sie_block->dxc;
155 break;
156 case PGM_PROTECTION:
157 pgm_info->trans_exc_code = vcpu->arch.sie_block->tecmc;
158 pgm_info->exc_access_id = vcpu->arch.sie_block->eai;
159 break;
160 default:
161 break;
162 }
163
164 if (vcpu->arch.sie_block->iprcc & PGM_PER) {
165 pgm_info->per_code = vcpu->arch.sie_block->perc;
166 pgm_info->per_atmid = vcpu->arch.sie_block->peratmid;
167 pgm_info->per_address = vcpu->arch.sie_block->peraddr;
168 pgm_info->per_access_id = vcpu->arch.sie_block->peraid;
169 }
170}
171
112static int handle_prog(struct kvm_vcpu *vcpu) 172static int handle_prog(struct kvm_vcpu *vcpu)
113{ 173{
174 struct kvm_s390_pgm_info pgm_info;
114 struct kvm_s390_itdb *itdb; 175 struct kvm_s390_itdb *itdb;
115 int rc; 176 int rc;
116 177
@@ -128,7 +189,9 @@ static int handle_prog(struct kvm_vcpu *vcpu)
128 memset(itdb, 0, sizeof(*itdb)); 189 memset(itdb, 0, sizeof(*itdb));
129skip_itdb: 190skip_itdb:
130 trace_kvm_s390_intercept_prog(vcpu, vcpu->arch.sie_block->iprcc); 191 trace_kvm_s390_intercept_prog(vcpu, vcpu->arch.sie_block->iprcc);
131 return kvm_s390_inject_program_int(vcpu, vcpu->arch.sie_block->iprcc); 192 __extract_prog_irq(vcpu, &pgm_info);
193
194 return kvm_s390_inject_prog_irq(vcpu, &pgm_info);
132} 195}
133 196
134static int handle_instruction_and_prog(struct kvm_vcpu *vcpu) 197static int handle_instruction_and_prog(struct kvm_vcpu *vcpu)