1 /* 2 * s390x Ultravisor related definitions 3 * 4 * Copyright (c) 2020 IBM Corp 5 * 6 * Authors: 7 * Janosch Frank <frankja@linux.ibm.com> 8 * 9 * This code is free software; you can redistribute it and/or modify it 10 * under the terms of the GNU General Public License version 2. 11 */ 12 #ifndef ASM_S390X_UV_H 13 #define ASM_S390X_UV_H 14 15 #define UVC_RC_EXECUTED 0x0001 16 #define UVC_RC_INV_CMD 0x0002 17 #define UVC_RC_INV_STATE 0x0003 18 #define UVC_RC_INV_LEN 0x0005 19 #define UVC_RC_NO_RESUME 0x0007 20 #define UVC_RC_INV_GHANDLE 0x0020 21 #define UVC_RC_INV_CHANDLE 0x0021 22 23 #define UVC_CMD_QUI 0x0001 24 #define UVC_CMD_INIT_UV 0x000f 25 #define UVC_CMD_CREATE_SEC_CONF 0x0100 26 #define UVC_CMD_DESTROY_SEC_CONF 0x0101 27 #define UVC_CMD_CREATE_SEC_CPU 0x0120 28 #define UVC_CMD_DESTROY_SEC_CPU 0x0121 29 #define UVC_CMD_CONV_TO_SEC_STOR 0x0200 30 #define UVC_CMD_CONV_FROM_SEC_STOR 0x0201 31 #define UVC_CMD_SET_SEC_CONF_PARAMS 0x0300 32 #define UVC_CMD_UNPACK_IMG 0x0301 33 #define UVC_CMD_VERIFY_IMG 0x0302 34 #define UVC_CMD_CPU_RESET 0x0310 35 #define UVC_CMD_CPU_RESET_INITIAL 0x0311 36 #define UVC_CMD_PERF_CONF_CLEAR_RESET 0x0320 37 #define UVC_CMD_CPU_RESET_CLEAR 0x0321 38 #define UVC_CMD_CPU_SET_STATE 0x0330 39 #define UVC_CMD_SET_UNSHARED_ALL 0x0340 40 #define UVC_CMD_PIN_PAGE_SHARED 0x0341 41 #define UVC_CMD_UNPIN_PAGE_SHARED 0x0342 42 #define UVC_CMD_SET_SHARED_ACCESS 0x1000 43 #define UVC_CMD_REMOVE_SHARED_ACCESS 0x1001 44 45 /* Bits in installed uv calls */ 46 enum uv_cmds_inst { 47 BIT_UVC_CMD_QUI = 0, 48 BIT_UVC_CMD_INIT_UV = 1, 49 BIT_UVC_CMD_CREATE_SEC_CONF = 2, 50 BIT_UVC_CMD_DESTROY_SEC_CONF = 3, 51 BIT_UVC_CMD_CREATE_SEC_CPU = 4, 52 BIT_UVC_CMD_DESTROY_SEC_CPU = 5, 53 BIT_UVC_CMD_CONV_TO_SEC_STOR = 6, 54 BIT_UVC_CMD_CONV_FROM_SEC_STOR = 7, 55 BIT_UVC_CMD_SET_SHARED_ACCESS = 8, 56 BIT_UVC_CMD_REMOVE_SHARED_ACCESS = 9, 57 BIT_UVC_CMD_SET_SEC_PARMS = 11, 58 BIT_UVC_CMD_UNPACK_IMG = 13, 59 BIT_UVC_CMD_VERIFY_IMG = 14, 60 BIT_UVC_CMD_CPU_RESET = 15, 61 BIT_UVC_CMD_CPU_RESET_INITIAL = 16, 62 BIT_UVC_CMD_CPU_SET_STATE = 17, 63 BIT_UVC_CMD_PREPARE_CLEAR_RESET = 18, 64 BIT_UVC_CMD_CPU_PERFORM_CLEAR_RESET = 19, 65 BIT_UVC_CMD_UNSHARE_ALL = 20, 66 BIT_UVC_CMD_PIN_PAGE_SHARED = 21, 67 BIT_UVC_CMD_UNPIN_PAGE_SHARED = 22, 68 }; 69 70 struct uv_cb_header { 71 u16 len; 72 u16 cmd; /* Command Code */ 73 u16 rc; /* Response Code */ 74 u16 rrc; /* Return Reason Code */ 75 } __attribute__((packed)) __attribute__((aligned(8))); 76 77 struct uv_cb_init { 78 struct uv_cb_header header; 79 u64 reserved08[2]; 80 u64 stor_origin; 81 u64 stor_len; 82 u64 reserved28[4]; 83 84 } __attribute__((packed)) __attribute__((aligned(8))); 85 86 struct uv_cb_qui { 87 struct uv_cb_header header; 88 u64 reserved08; 89 u64 inst_calls_list[4]; 90 u64 reserved30[2]; 91 u64 uv_base_stor_len; 92 u64 reserved48; 93 u64 conf_base_phys_stor_len; 94 u64 conf_base_virt_stor_len; 95 u64 conf_virt_var_stor_len; 96 u64 cpu_stor_len; 97 u32 reserved70[3]; 98 u32 max_num_sec_conf; 99 u64 max_guest_stor_addr; 100 u8 reserved88[158 - 136]; 101 u16 max_guest_cpus; 102 u8 reserveda0[200 - 160]; 103 } __attribute__((packed)) __attribute__((aligned(8))); 104 105 struct uv_cb_cgc { 106 struct uv_cb_header header; 107 u64 reserved08[2]; 108 u64 guest_handle; 109 u64 conf_base_stor_origin; 110 u64 conf_var_stor_origin; 111 u64 reserved30; 112 u64 guest_stor_origin; 113 u64 guest_stor_len; 114 u64 guest_sca; 115 u64 guest_asce; 116 u64 reserved60[5]; 117 } __attribute__((packed)) __attribute__((aligned(8))); 118 119 struct uv_cb_csc { 120 struct uv_cb_header header; 121 u64 reserved08[2]; 122 u64 cpu_handle; 123 u64 guest_handle; 124 u64 stor_origin; 125 u8 reserved30[6]; 126 u16 num; 127 u64 state_origin; 128 u64 reserved[4]; 129 } __attribute__((packed)) __attribute__((aligned(8))); 130 131 struct uv_cb_unp { 132 struct uv_cb_header header; 133 u64 reserved08[2]; 134 u64 guest_handle; 135 u64 gaddr; 136 u64 tweak[2]; 137 u64 reserved38[3]; 138 } __attribute__((packed)) __attribute__((aligned(8))); 139 140 /* 141 * A common UV call struct for the following calls: 142 * Destroy cpu/config 143 * Verify 144 */ 145 struct uv_cb_nodata { 146 struct uv_cb_header header; 147 u64 reserved08[2]; 148 u64 handle; 149 u64 reserved20[4]; 150 } __attribute__((packed)) __attribute__((aligned(8))); 151 152 struct uv_cb_share { 153 struct uv_cb_header header; 154 u64 reserved08[3]; 155 u64 paddr; 156 u64 reserved28; 157 } __attribute__((packed)) __attribute__((aligned(8))); 158 159 /* Convert to Secure */ 160 struct uv_cb_cts { 161 struct uv_cb_header header; 162 u64 reserved08[2]; 163 u64 guest_handle; 164 u64 gaddr; 165 } __attribute__((packed)) __attribute__((aligned(8))); 166 167 /* Convert from Secure / Pin Page Shared */ 168 struct uv_cb_cfs { 169 struct uv_cb_header header; 170 u64 reserved08[2]; 171 u64 paddr; 172 } __attribute__((packed)) __attribute__((aligned(8))); 173 174 /* Set Secure Config Parameter */ 175 struct uv_cb_ssc { 176 struct uv_cb_header header; 177 u64 reserved08[2]; 178 u64 guest_handle; 179 u64 sec_header_origin; 180 u32 sec_header_len; 181 u32 reserved2c; 182 u64 reserved30[4]; 183 } __attribute__((packed)) __attribute__((aligned(8))); 184 185 static inline int uv_call_once(unsigned long r1, unsigned long r2) 186 { 187 int cc; 188 189 asm volatile( 190 "0: .insn rrf,0xB9A40000,%[r1],%[r2],0,0\n" 191 " ipm %[cc]\n" 192 " srl %[cc],28\n" 193 : [cc] "=d" (cc) 194 : [r1] "a" (r1), [r2] "a" (r2) 195 : "memory", "cc"); 196 return cc; 197 } 198 199 static inline int uv_call(unsigned long r1, unsigned long r2) 200 { 201 int cc; 202 203 /* 204 * CC 2 and 3 tell us to re-execute because the instruction 205 * hasn't yet finished. 206 */ 207 do { 208 cc = uv_call_once(r1, r2); 209 } while (cc > 1); 210 211 return cc; 212 } 213 214 static inline int share(unsigned long addr, u16 cmd) 215 { 216 struct uv_cb_share uvcb = { 217 .header.cmd = cmd, 218 .header.len = sizeof(uvcb), 219 .paddr = addr 220 }; 221 int cc; 222 223 cc = uv_call(0, (u64)&uvcb); 224 if (!cc && uvcb.header.rc == UVC_RC_EXECUTED) 225 return 0; 226 227 report_info("uv_call: cmd %04x cc %d response code: %04x", cc, cmd, 228 uvcb.header.rc); 229 return -1; 230 } 231 232 /* 233 * Guest 2 request to the Ultravisor to make a page shared with the 234 * hypervisor for IO. 235 * 236 * @addr: Real or absolute address of the page to be shared 237 */ 238 static inline int uv_set_shared(unsigned long addr) 239 { 240 return share(addr, UVC_CMD_SET_SHARED_ACCESS); 241 } 242 243 /* 244 * Guest 2 request to the Ultravisor to make a page unshared. 245 * 246 * @addr: Real or absolute address of the page to be unshared 247 */ 248 static inline int uv_remove_shared(unsigned long addr) 249 { 250 return share(addr, UVC_CMD_REMOVE_SHARED_ACCESS); 251 } 252 253 struct uv_cb_cpu_set_state { 254 struct uv_cb_header header; 255 u64 reserved08[2]; 256 u64 cpu_handle; 257 u8 reserved20[7]; 258 u8 state; 259 u64 reserved28[5]; 260 }; 261 262 #define PV_CPU_STATE_OPR 1 263 #define PV_CPU_STATE_STP 2 264 #define PV_CPU_STATE_CHKSTP 3 265 #define PV_CPU_STATE_OPR_LOAD 5 266 267 #endif 268