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.

Signed-off-by: Janosch Frank <frankja@linux.vnet.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Fixes: a7e19ab ("KVM: s390: handle missing storage-key facility")
Cc: <stable@vger.kernel.org> # v4.8+
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>

authored by Janosch Frank and committed by Christian Borntraeger ca76ec9c bb64da9a

+9 -2
+9 -2
arch/s390/kvm/priv.c
··· 232 232 VCPU_EVENT(vcpu, 4, "%s", "retrying storage key operation"); 233 233 return -EAGAIN; 234 234 } 235 - if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) 236 - return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); 237 235 return 0; 238 236 } 239 237 ··· 241 243 unsigned char key; 242 244 int reg1, reg2; 243 245 int rc; 246 + 247 + if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) 248 + return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); 244 249 245 250 rc = try_handle_skey(vcpu); 246 251 if (rc) ··· 273 272 unsigned long addr; 274 273 int reg1, reg2; 275 274 int rc; 275 + 276 + if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) 277 + return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); 276 278 277 279 rc = try_handle_skey(vcpu); 278 280 if (rc) ··· 311 307 unsigned char key, oldkey; 312 308 int reg1, reg2; 313 309 int rc; 310 + 311 + if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) 312 + return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); 314 313 315 314 rc = try_handle_skey(vcpu); 316 315 if (rc)