s390: fix support for z16 systems.

-----BEGIN PGP SIGNATURE-----
 
 iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmaHstsUHHBib256aW5p
 QHJlZGhhdC5jb20ACgkQv/vSX3jHroPg2Qf+IUHv0lUOiPtbanMpwAWuXVLUFUOs
 QxhzcKKmi/Det9gkgYA6SQEtr0nR22FIE50+lRFex9gCLeaFIizVCKtvm9vi5pKe
 IpJ3sNAO88O/ehxurdBJ4ueADybruXyyKeQfpPKBoPiUAJpr85BYIpRbXwTyJTok
 eCFQS39jvTN2YMyGrD7zdKBOcf3V3Da/m1v4f5bAx8nRYQNPLFX1GFbJG8gzQ8wN
 DnYlDiKBzu8BOnBkdQh53Oz2e6a5gU3EHo9ZGITOr6Fmu4tGuXBkZ50pwaIdXD52
 ZSZdMfbYJr7cWg2H6z3rqfIgO32uCGzHX7ZR8s3JbckVvQyaO4zL14ZW7w==
 =szz2
 -----END PGP SIGNATURE-----

Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm

Pull kvm fix from Paolo Bonzini:

 - s390: fix support for z16 systems

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
  KVM: s390: fix LPSWEY handling
This commit is contained in:
Linus Torvalds 2024-07-05 11:23:30 -07:00
commit 75aa87ca48
4 changed files with 49 additions and 0 deletions

View File

@ -427,6 +427,7 @@ struct kvm_vcpu_stat {
u64 instruction_io_other;
u64 instruction_lpsw;
u64 instruction_lpswe;
u64 instruction_lpswey;
u64 instruction_pfmf;
u64 instruction_ptff;
u64 instruction_sck;

View File

@ -132,6 +132,7 @@ const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
STATS_DESC_COUNTER(VCPU, instruction_io_other),
STATS_DESC_COUNTER(VCPU, instruction_lpsw),
STATS_DESC_COUNTER(VCPU, instruction_lpswe),
STATS_DESC_COUNTER(VCPU, instruction_lpswey),
STATS_DESC_COUNTER(VCPU, instruction_pfmf),
STATS_DESC_COUNTER(VCPU, instruction_ptff),
STATS_DESC_COUNTER(VCPU, instruction_sck),

View File

@ -138,6 +138,21 @@ static inline u64 kvm_s390_get_base_disp_s(struct kvm_vcpu *vcpu, u8 *ar)
return (base2 ? vcpu->run->s.regs.gprs[base2] : 0) + disp2;
}
static inline u64 kvm_s390_get_base_disp_siy(struct kvm_vcpu *vcpu, u8 *ar)
{
u32 base1 = vcpu->arch.sie_block->ipb >> 28;
s64 disp1;
/* The displacement is a 20bit _SIGNED_ value */
disp1 = sign_extend64(((vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16) +
((vcpu->arch.sie_block->ipb & 0xff00) << 4), 19);
if (ar)
*ar = base1;
return (base1 ? vcpu->run->s.regs.gprs[base1] : 0) + disp1;
}
static inline void kvm_s390_get_base_disp_sse(struct kvm_vcpu *vcpu,
u64 *address1, u64 *address2,
u8 *ar_b1, u8 *ar_b2)

View File

@ -797,6 +797,36 @@ static int handle_lpswe(struct kvm_vcpu *vcpu)
return 0;
}
static int handle_lpswey(struct kvm_vcpu *vcpu)
{
psw_t new_psw;
u64 addr;
int rc;
u8 ar;
vcpu->stat.instruction_lpswey++;
if (!test_kvm_facility(vcpu->kvm, 193))
return kvm_s390_inject_program_int(vcpu, PGM_OPERATION);
if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
addr = kvm_s390_get_base_disp_siy(vcpu, &ar);
if (addr & 7)
return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
rc = read_guest(vcpu, addr, ar, &new_psw, sizeof(new_psw));
if (rc)
return kvm_s390_inject_prog_cond(vcpu, rc);
vcpu->arch.sie_block->gpsw = new_psw;
if (!is_valid_psw(&vcpu->arch.sie_block->gpsw))
return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
return 0;
}
static int handle_stidp(struct kvm_vcpu *vcpu)
{
u64 stidp_data = vcpu->kvm->arch.model.cpuid;
@ -1462,6 +1492,8 @@ int kvm_s390_handle_eb(struct kvm_vcpu *vcpu)
case 0x61:
case 0x62:
return handle_ri(vcpu);
case 0x71:
return handle_lpswey(vcpu);
default:
return -EOPNOTSUPP;
}