diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/s390/include/asm/kvm_host.h | 18 | ||||
-rw-r--r-- | arch/s390/kvm/intercept.c | 65 |
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 | ||
112 | static 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 | |||
112 | static int handle_prog(struct kvm_vcpu *vcpu) | 172 | static 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)); |
129 | skip_itdb: | 190 | skip_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 | ||
134 | static int handle_instruction_and_prog(struct kvm_vcpu *vcpu) | 197 | static int handle_instruction_and_prog(struct kvm_vcpu *vcpu) |