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