Skip to content

Commit 17a5e09

Browse files
committed
KVM: s390: fix LPSWEY handling
jira LE-3201 Rebuild_History Non-Buildable kernel-rt-4.18.0-553.22.1.rt7.363.el8_10 commit-author Christian Borntraeger <borntraeger@linux.ibm.com> commit 4c6abb7 in rare cases, e.g. for injecting a machine check we do intercept all load PSW instructions via ICTL_LPSW. With facility 193 a new variant LPSWEY was added. KVM needs to handle that as well. Fixes: a3efa84 ("KVM: s390: gen_facilities: allow facilities 165, 193, 194 and 196") Reported-by: Marc Hartmayer <mhartmay@linux.ibm.com> Reviewed-by: Sven Schnelle <svens@linux.ibm.com> Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@linux.ibm.com> Message-ID: <20240628163547.2314-1-borntraeger@linux.ibm.com> (cherry picked from commit 4c6abb7) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
1 parent fda3e4a commit 17a5e09

File tree

4 files changed

+49
-0
lines changed

4 files changed

+49
-0
lines changed

arch/s390/include/asm/kvm_host.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,7 @@ struct kvm_vcpu_stat {
426426
u64 instruction_io_other;
427427
u64 instruction_lpsw;
428428
u64 instruction_lpswe;
429+
u64 instruction_lpswey;
429430
u64 instruction_pfmf;
430431
u64 instruction_ptff;
431432
u64 instruction_sck;

arch/s390/kvm/kvm-s390.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
131131
STATS_DESC_COUNTER(VCPU, instruction_io_other),
132132
STATS_DESC_COUNTER(VCPU, instruction_lpsw),
133133
STATS_DESC_COUNTER(VCPU, instruction_lpswe),
134+
STATS_DESC_COUNTER(VCPU, instruction_lpswey),
134135
STATS_DESC_COUNTER(VCPU, instruction_pfmf),
135136
STATS_DESC_COUNTER(VCPU, instruction_ptff),
136137
STATS_DESC_COUNTER(VCPU, instruction_sck),

arch/s390/kvm/kvm-s390.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,21 @@ static inline u64 kvm_s390_get_base_disp_s(struct kvm_vcpu *vcpu, u8 *ar)
120120
return (base2 ? vcpu->run->s.regs.gprs[base2] : 0) + disp2;
121121
}
122122

123+
static inline u64 kvm_s390_get_base_disp_siy(struct kvm_vcpu *vcpu, u8 *ar)
124+
{
125+
u32 base1 = vcpu->arch.sie_block->ipb >> 28;
126+
s64 disp1;
127+
128+
/* The displacement is a 20bit _SIGNED_ value */
129+
disp1 = sign_extend64(((vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16) +
130+
((vcpu->arch.sie_block->ipb & 0xff00) << 4), 19);
131+
132+
if (ar)
133+
*ar = base1;
134+
135+
return (base1 ? vcpu->run->s.regs.gprs[base1] : 0) + disp1;
136+
}
137+
123138
static inline void kvm_s390_get_base_disp_sse(struct kvm_vcpu *vcpu,
124139
u64 *address1, u64 *address2,
125140
u8 *ar_b1, u8 *ar_b2)

arch/s390/kvm/priv.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,36 @@ static int handle_lpswe(struct kvm_vcpu *vcpu)
800800
return 0;
801801
}
802802

803+
static int handle_lpswey(struct kvm_vcpu *vcpu)
804+
{
805+
psw_t new_psw;
806+
u64 addr;
807+
int rc;
808+
u8 ar;
809+
810+
vcpu->stat.instruction_lpswey++;
811+
812+
if (!test_kvm_facility(vcpu->kvm, 193))
813+
return kvm_s390_inject_program_int(vcpu, PGM_OPERATION);
814+
815+
if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
816+
return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
817+
818+
addr = kvm_s390_get_base_disp_siy(vcpu, &ar);
819+
if (addr & 7)
820+
return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
821+
822+
rc = read_guest(vcpu, addr, ar, &new_psw, sizeof(new_psw));
823+
if (rc)
824+
return kvm_s390_inject_prog_cond(vcpu, rc);
825+
826+
vcpu->arch.sie_block->gpsw = new_psw;
827+
if (!is_valid_psw(&vcpu->arch.sie_block->gpsw))
828+
return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
829+
830+
return 0;
831+
}
832+
803833
static int handle_stidp(struct kvm_vcpu *vcpu)
804834
{
805835
u64 stidp_data = vcpu->kvm->arch.model.cpuid;
@@ -1465,6 +1495,8 @@ int kvm_s390_handle_eb(struct kvm_vcpu *vcpu)
14651495
case 0x61:
14661496
case 0x62:
14671497
return handle_ri(vcpu);
1498+
case 0x71:
1499+
return handle_lpswey(vcpu);
14681500
default:
14691501
return -EOPNOTSUPP;
14701502
}

0 commit comments

Comments
 (0)