History

KVM: s390: Fix skey emulation permission check

All skey functions call skey_check_enable at their start, which checks if we are in the PSTATE and injects a privileged operation exception if we are. Unfortunately they continue processing afterwards and perform the operation anyhow as skey_check_enable does not deliver an error if the exception injection was successful. Let's move the PSTATE check into the skey functions and exit them on such an occasion, also we now do not enable skey handling anymore in such a case.

Janosch Frank committed 8 years ago

Commit ca76ec91 parent bb64da91 file · +9 −2Browse files

Unified · Split

arch/s390/kvm/priv.c+9−2
@@ -232,8 +232,6 @@ static int try_handle_skey(struct kvm_vcpu *vcpu) · 231 unmodified lines
232232 VCPU_EVENT(vcpu, 4, "%s", "retrying storage key operation");
233233 return -EAGAIN;
234234 }
235− if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
236− return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
237235 return 0;
238236 }
239237
@@ -244,6 +242,9 @@ static int handle_iske(struct kvm_vcpu *vcpu) · 4 unmodified lines
244242 int reg1, reg2;
245243 int rc;
246244
245+ if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
246+ return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
247+
247248 rc = try_handle_skey(vcpu);
248249 if (rc)
249250 return rc != -EAGAIN ? rc : 0;
@@ -273,6 +274,9 @@ static int handle_rrbe(struct kvm_vcpu *vcpu) · 23 unmodified lines
273274 int reg1, reg2;
274275 int rc;
275276
277+ if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
278+ return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
279+
276280 rc = try_handle_skey(vcpu);
277281 if (rc)
278282 return rc != -EAGAIN ? rc : 0;
@@ -308,6 +312,9 @@ static int handle_sske(struct kvm_vcpu *vcpu) · 29 unmodified lines
308312 int reg1, reg2;
309313 int rc;
310314
315+ if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
316+ return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
317+
311318 rc = try_handle_skey(vcpu);
312319 if (rc)
313320 return rc != -EAGAIN ? rc : 0;