Commit 0c02cc57 authored by Heiko Carstens's avatar Heiko Carstens

KVM: s390: fix sthyi error handling

Commit 9fb6c9b3 ("s390/sthyi: add cache to store hypervisor info")
added cache handling for store hypervisor info. This also changed the
possible return code for sthyi_fill().

Instead of only returning a condition code like the sthyi instruction would
do, it can now also return a negative error value (-ENOMEM). handle_styhi()
was not changed accordingly. In case of an error, the negative error value
would incorrectly injected into the guest PSW.

Add proper error handling to prevent this, and update the comment which
describes the possible return values of sthyi_fill().

Fixes: 9fb6c9b3 ("s390/sthyi: add cache to store hypervisor info")
Reviewed-by: default avatarChristian Borntraeger <borntraeger@linux.ibm.com>
Link: https://lore.kernel.org/r/20230727182939.2050744-1-hca@linux.ibm.comSigned-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
parent 26087667
...@@ -459,9 +459,9 @@ static int sthyi_update_cache(u64 *rc) ...@@ -459,9 +459,9 @@ static int sthyi_update_cache(u64 *rc)
* *
* Fills the destination with system information returned by the STHYI * Fills the destination with system information returned by the STHYI
* instruction. The data is generated by emulation or execution of STHYI, * instruction. The data is generated by emulation or execution of STHYI,
* if available. The return value is the condition code that would be * if available. The return value is either a negative error value or
* returned, the rc parameter is the return code which is passed in * the condition code that would be returned, the rc parameter is the
* register R2 + 1. * return code which is passed in register R2 + 1.
*/ */
int sthyi_fill(void *dst, u64 *rc) int sthyi_fill(void *dst, u64 *rc)
{ {
......
...@@ -389,8 +389,8 @@ static int handle_partial_execution(struct kvm_vcpu *vcpu) ...@@ -389,8 +389,8 @@ static int handle_partial_execution(struct kvm_vcpu *vcpu)
*/ */
int handle_sthyi(struct kvm_vcpu *vcpu) int handle_sthyi(struct kvm_vcpu *vcpu)
{ {
int reg1, reg2, r = 0; int reg1, reg2, cc = 0, r = 0;
u64 code, addr, cc = 0, rc = 0; u64 code, addr, rc = 0;
struct sthyi_sctns *sctns = NULL; struct sthyi_sctns *sctns = NULL;
if (!test_kvm_facility(vcpu->kvm, 74)) if (!test_kvm_facility(vcpu->kvm, 74))
...@@ -421,7 +421,10 @@ int handle_sthyi(struct kvm_vcpu *vcpu) ...@@ -421,7 +421,10 @@ int handle_sthyi(struct kvm_vcpu *vcpu)
return -ENOMEM; return -ENOMEM;
cc = sthyi_fill(sctns, &rc); cc = sthyi_fill(sctns, &rc);
if (cc < 0) {
free_page((unsigned long)sctns);
return cc;
}
out: out:
if (!cc) { if (!cc) {
if (kvm_s390_pv_cpu_is_protected(vcpu)) { if (kvm_s390_pv_cpu_is_protected(vcpu)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment