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