1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 #ifndef _S390X_SIE_H_ 3 #define _S390X_SIE_H_ 4 5 #include <stdint.h> 6 #include <asm/arch_def.h> 7 8 #define CPUSTAT_STOPPED 0x80000000 9 #define CPUSTAT_WAIT 0x10000000 10 #define CPUSTAT_ECALL_PEND 0x08000000 11 #define CPUSTAT_STOP_INT 0x04000000 12 #define CPUSTAT_IO_INT 0x02000000 13 #define CPUSTAT_EXT_INT 0x01000000 14 #define CPUSTAT_RUNNING 0x00800000 15 #define CPUSTAT_RETAINED 0x00400000 16 #define CPUSTAT_TIMING_SUB 0x00020000 17 #define CPUSTAT_SIE_SUB 0x00010000 18 #define CPUSTAT_RRF 0x00008000 19 #define CPUSTAT_SLSV 0x00004000 20 #define CPUSTAT_SLSR 0x00002000 21 #define CPUSTAT_ZARCH 0x00000800 22 #define CPUSTAT_MCDS 0x00000100 23 #define CPUSTAT_KSS 0x00000200 24 #define CPUSTAT_SM 0x00000080 25 #define CPUSTAT_IBS 0x00000040 26 #define CPUSTAT_GED2 0x00000010 27 #define CPUSTAT_G 0x00000008 28 #define CPUSTAT_GED 0x00000004 29 #define CPUSTAT_J 0x00000002 30 #define CPUSTAT_P 0x00000001 31 32 struct kvm_s390_sie_block { 33 uint32_t cpuflags; /* 0x0000 */ 34 uint32_t : 1; /* 0x0004 */ 35 uint32_t prefix : 18; 36 uint32_t : 1; 37 uint32_t ibc : 12; 38 uint8_t reserved08[4]; /* 0x0008 */ 39 #define PROG_IN_SIE (1<<0) 40 uint32_t prog0c; /* 0x000c */ 41 uint8_t reserved10[16]; /* 0x0010 */ 42 #define PROG_BLOCK_SIE (1<<0) 43 #define PROG_REQUEST (1<<1) 44 uint32_t prog20; /* 0x0020 */ 45 uint8_t reserved24[4]; /* 0x0024 */ 46 uint64_t cputm; /* 0x0028 */ 47 uint64_t ckc; /* 0x0030 */ 48 uint64_t epoch; /* 0x0038 */ 49 uint32_t svcc; /* 0x0040 */ 50 #define LCTL_CR0 0x8000 51 #define LCTL_CR6 0x0200 52 #define LCTL_CR9 0x0040 53 #define LCTL_CR10 0x0020 54 #define LCTL_CR11 0x0010 55 #define LCTL_CR14 0x0002 56 uint16_t lctl; /* 0x0044 */ 57 int16_t icpua; /* 0x0046 */ 58 #define ICTL_OPEREXC 0x80000000 59 #define ICTL_PINT 0x20000000 60 #define ICTL_LPSW 0x00400000 61 #define ICTL_STCTL 0x00040000 62 #define ICTL_ISKE 0x00004000 63 #define ICTL_SSKE 0x00002000 64 #define ICTL_RRBE 0x00001000 65 #define ICTL_TPROT 0x00000200 66 uint32_t ictl; /* 0x0048 */ 67 #define ECA_CEI 0x80000000 68 #define ECA_IB 0x40000000 69 #define ECA_SIGPI 0x10000000 70 #define ECA_MVPGI 0x01000000 71 #define ECA_AIV 0x00200000 72 #define ECA_VX 0x00020000 73 #define ECA_PROTEXCI 0x00002000 74 #define ECA_APIE 0x00000008 75 #define ECA_SII 0x00000001 76 uint32_t eca; /* 0x004c */ 77 #define ICPT_INST 0x04 78 #define ICPT_PROGI 0x08 79 #define ICPT_INSTPROGI 0x0C 80 #define ICPT_EXTREQ 0x10 81 #define ICPT_EXTINT 0x14 82 #define ICPT_IOREQ 0x18 83 #define ICPT_WAIT 0x1c 84 #define ICPT_VALIDITY 0x20 85 #define ICPT_STOP 0x28 86 #define ICPT_OPEREXC 0x2C 87 #define ICPT_PARTEXEC 0x38 88 #define ICPT_IOINST 0x40 89 #define ICPT_KSS 0x5c 90 uint8_t icptcode; /* 0x0050 */ 91 uint8_t icptstatus; /* 0x0051 */ 92 uint16_t ihcpu; /* 0x0052 */ 93 uint8_t reserved54[2]; /* 0x0054 */ 94 uint16_t ipa; /* 0x0056 */ 95 uint32_t ipb; /* 0x0058 */ 96 uint32_t scaoh; /* 0x005c */ 97 #define FPF_BPBC 0x20 98 uint8_t fpf; /* 0x0060 */ 99 #define ECB_GS 0x40 100 #define ECB_TE 0x10 101 #define ECB_SPECI 0x08 102 #define ECB_SRSI 0x04 103 #define ECB_HOSTPROTINT 0x02 104 uint8_t ecb; /* 0x0061 */ 105 #define ECB2_CMMA 0x80 106 #define ECB2_IEP 0x20 107 #define ECB2_PFMFI 0x08 108 #define ECB2_ESCA 0x04 109 uint8_t ecb2; /* 0x0062 */ 110 #define ECB3_DEA 0x08 111 #define ECB3_AES 0x04 112 #define ECB3_RI 0x01 113 uint8_t ecb3; /* 0x0063 */ 114 uint32_t scaol; /* 0x0064 */ 115 uint8_t reserved68; /* 0x0068 */ 116 uint8_t epdx; /* 0x0069 */ 117 uint8_t reserved6a[2]; /* 0x006a */ 118 uint32_t todpr; /* 0x006c */ 119 #define GISA_FORMAT1 0x00000001 120 uint32_t gd; /* 0x0070 */ 121 uint8_t reserved74[12]; /* 0x0074 */ 122 uint64_t mso; /* 0x0080 */ 123 uint64_t msl; /* 0x0088 */ 124 struct psw gpsw; /* 0x0090 */ 125 uint64_t gg14; /* 0x00a0 */ 126 uint64_t gg15; /* 0x00a8 */ 127 uint8_t reservedb0[8]; /* 0x00b0 */ 128 #define HPID_KVM 0x4 129 #define HPID_VSIE 0x5 130 uint8_t hpid; /* 0x00b8 */ 131 uint8_t reservedb9[11]; /* 0x00b9 */ 132 uint16_t extcpuaddr; /* 0x00c4 */ 133 uint16_t eic; /* 0x00c6 */ 134 uint32_t reservedc8; /* 0x00c8 */ 135 uint16_t pgmilc; /* 0x00cc */ 136 uint16_t iprcc; /* 0x00ce */ 137 uint32_t dxc; /* 0x00d0 */ 138 uint16_t mcn; /* 0x00d4 */ 139 uint8_t perc; /* 0x00d6 */ 140 uint8_t peratmid; /* 0x00d7 */ 141 uint64_t peraddr; /* 0x00d8 */ 142 uint8_t eai; /* 0x00e0 */ 143 uint8_t peraid; /* 0x00e1 */ 144 uint8_t oai; /* 0x00e2 */ 145 uint8_t armid; /* 0x00e3 */ 146 uint8_t reservede4[4]; /* 0x00e4 */ 147 uint64_t tecmc; /* 0x00e8 */ 148 uint8_t reservedf0[12]; /* 0x00f0 */ 149 #define CRYCB_FORMAT_MASK 0x00000003 150 #define CRYCB_FORMAT0 0x00000000 151 #define CRYCB_FORMAT1 0x00000001 152 #define CRYCB_FORMAT2 0x00000003 153 uint32_t crycbd; /* 0x00fc */ 154 uint64_t gcr[16]; /* 0x0100 */ 155 uint64_t gbea; /* 0x0180 */ 156 uint8_t reserved188[8]; /* 0x0188 */ 157 uint64_t sdnxo; /* 0x0190 */ 158 uint8_t reserved198[8]; /* 0x0198 */ 159 uint32_t fac; /* 0x01a0 */ 160 uint8_t reserved1a4[20]; /* 0x01a4 */ 161 uint64_t cbrlo; /* 0x01b8 */ 162 uint8_t reserved1c0[8]; /* 0x01c0 */ 163 #define ECD_HOSTREGMGMT 0x20000000 164 #define ECD_MEF 0x08000000 165 #define ECD_ETOKENF 0x02000000 166 #define ECD_ECC 0x00200000 167 uint32_t ecd; /* 0x01c8 */ 168 uint8_t reserved1cc[18]; /* 0x01cc */ 169 uint64_t pp; /* 0x01de */ 170 uint8_t reserved1e6[2]; /* 0x01e6 */ 171 uint64_t itdba; /* 0x01e8 */ 172 uint64_t riccbd; /* 0x01f0 */ 173 uint64_t gvrd; /* 0x01f8 */ 174 } __attribute__((packed)); 175 176 struct vm_save_regs { 177 uint64_t grs[16]; 178 uint64_t fprs[16]; 179 uint32_t fpc; 180 }; 181 182 /* We might be able to nestle all of this into the stack frame. But 183 * having a dedicated save area that saves more than the s390 ELF ABI 184 * defines leaves us more freedom in the implementation. 185 */ 186 struct vm_save_area { 187 struct vm_save_regs guest; 188 struct vm_save_regs host; 189 }; 190 191 struct vm { 192 struct kvm_s390_sie_block *sblk; 193 struct vm_save_area save_area; 194 uint8_t *crycb; /* Crypto Control Block */ 195 /* Ptr to first guest page */ 196 uint8_t *guest_mem; 197 }; 198 199 extern void sie_entry(void); 200 extern void sie_exit(void); 201 extern void sie64a(struct kvm_s390_sie_block *sblk, struct vm_save_area *save_area); 202 void sie(struct vm *vm); 203 void sie_expect_validity(void); 204 void sie_check_validity(uint16_t vir_exp); 205 void sie_handle_validity(struct vm *vm); 206 void sie_guest_create(struct vm *vm, uint64_t guest_mem, uint64_t guest_mem_len); 207 void sie_guest_destroy(struct vm *vm); 208 209 #endif /* _S390X_SIE_H_ */ 210