1*dc142414SNina Schoetterl-Glausch /* SPDX-License-Identifier: GPL-2.0-only */ 2*dc142414SNina Schoetterl-Glausch /* 3*dc142414SNina Schoetterl-Glausch * Functionality for SIE interception handling. 4*dc142414SNina Schoetterl-Glausch * 5*dc142414SNina Schoetterl-Glausch * Copyright IBM Corp. 2024 6*dc142414SNina Schoetterl-Glausch */ 7*dc142414SNina Schoetterl-Glausch 8*dc142414SNina Schoetterl-Glausch #include <sie-icpt.h> 9*dc142414SNina Schoetterl-Glausch sblk_ip_as_diag(struct kvm_s390_sie_block * sblk)10*dc142414SNina Schoetterl-Glauschstruct diag_itext sblk_ip_as_diag(struct kvm_s390_sie_block *sblk) 11*dc142414SNina Schoetterl-Glausch { 12*dc142414SNina Schoetterl-Glausch union { 13*dc142414SNina Schoetterl-Glausch struct { 14*dc142414SNina Schoetterl-Glausch uint64_t ipa : 16; 15*dc142414SNina Schoetterl-Glausch uint64_t ipb : 32; 16*dc142414SNina Schoetterl-Glausch uint64_t : 16; 17*dc142414SNina Schoetterl-Glausch }; 18*dc142414SNina Schoetterl-Glausch struct diag_itext diag; 19*dc142414SNina Schoetterl-Glausch } instr = { .ipa = sblk->ipa, .ipb = sblk->ipb }; 20*dc142414SNina Schoetterl-Glausch 21*dc142414SNina Schoetterl-Glausch return instr.diag; 22*dc142414SNina Schoetterl-Glausch } 23*dc142414SNina Schoetterl-Glausch sie_is_diag_icpt(struct vm * vm,unsigned int diag)24*dc142414SNina Schoetterl-Glauschbool sie_is_diag_icpt(struct vm *vm, unsigned int diag) 25*dc142414SNina Schoetterl-Glausch { 26*dc142414SNina Schoetterl-Glausch struct diag_itext instr = sblk_ip_as_diag(vm->sblk); 27*dc142414SNina Schoetterl-Glausch uint8_t icptcode; 28*dc142414SNina Schoetterl-Glausch uint64_t code; 29*dc142414SNina Schoetterl-Glausch 30*dc142414SNina Schoetterl-Glausch switch (diag) { 31*dc142414SNina Schoetterl-Glausch case 0x44: 32*dc142414SNina Schoetterl-Glausch case 0x9c: 33*dc142414SNina Schoetterl-Glausch case 0x288: 34*dc142414SNina Schoetterl-Glausch case 0x308: 35*dc142414SNina Schoetterl-Glausch icptcode = ICPT_PV_NOTIFY; 36*dc142414SNina Schoetterl-Glausch break; 37*dc142414SNina Schoetterl-Glausch case 0x500: 38*dc142414SNina Schoetterl-Glausch icptcode = ICPT_PV_INSTR; 39*dc142414SNina Schoetterl-Glausch break; 40*dc142414SNina Schoetterl-Glausch default: 41*dc142414SNina Schoetterl-Glausch /* If a new diag is introduced add it to the cases above! */ 42*dc142414SNina Schoetterl-Glausch assert_msg(false, "unknown diag 0x%x", diag); 43*dc142414SNina Schoetterl-Glausch } 44*dc142414SNina Schoetterl-Glausch 45*dc142414SNina Schoetterl-Glausch if (sie_is_pv(vm)) { 46*dc142414SNina Schoetterl-Glausch if (instr.r_1 != 0 || instr.r_2 != 2 || instr.r_base != 5) 47*dc142414SNina Schoetterl-Glausch return false; 48*dc142414SNina Schoetterl-Glausch if (instr.displace) 49*dc142414SNina Schoetterl-Glausch return false; 50*dc142414SNina Schoetterl-Glausch } else { 51*dc142414SNina Schoetterl-Glausch icptcode = ICPT_INST; 52*dc142414SNina Schoetterl-Glausch } 53*dc142414SNina Schoetterl-Glausch if (vm->sblk->icptcode != icptcode) 54*dc142414SNina Schoetterl-Glausch return false; 55*dc142414SNina Schoetterl-Glausch if (instr.opcode != 0x83 || instr.zero) 56*dc142414SNina Schoetterl-Glausch return false; 57*dc142414SNina Schoetterl-Glausch code = instr.r_base ? vm->save_area.guest.grs[instr.r_base] : 0; 58*dc142414SNina Schoetterl-Glausch code = (code + instr.displace) & 0xffff; 59*dc142414SNina Schoetterl-Glausch return code == diag; 60*dc142414SNina Schoetterl-Glausch } 61