1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Ultravisor Interfaces 4 * 5 * Copyright IBM Corp. 2019 6 * 7 * Author(s): 8 * Vasily Gorbik <gor@linux.ibm.com> 9 * Janosch Frank <frankja@linux.ibm.com> 10 */ 11 #ifndef _ASM_S390_UV_H 12 #define _ASM_S390_UV_H 13 14 #include <linux/types.h> 15 #include <linux/errno.h> 16 #include <linux/bug.h> 17 #include <linux/sched.h> 18 #include <asm/page.h> 19 #include <asm/gmap.h> 20 21 #define UVC_RC_EXECUTED 0x0001 22 #define UVC_RC_INV_CMD 0x0002 23 #define UVC_RC_INV_STATE 0x0003 24 #define UVC_RC_INV_LEN 0x0005 25 #define UVC_RC_NO_RESUME 0x0007 26 #define UVC_RC_NEED_DESTROY 0x8000 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_PIN_PAGE_SHARED 0x0341 40 #define UVC_CMD_UNPIN_PAGE_SHARED 0x0342 41 #define UVC_CMD_SET_SHARED_ACCESS 0x1000 42 #define UVC_CMD_REMOVE_SHARED_ACCESS 0x1001 43 44 /* Bits in installed uv calls */ 45 enum uv_cmds_inst { 46 BIT_UVC_CMD_QUI = 0, 47 BIT_UVC_CMD_INIT_UV = 1, 48 BIT_UVC_CMD_CREATE_SEC_CONF = 2, 49 BIT_UVC_CMD_DESTROY_SEC_CONF = 3, 50 BIT_UVC_CMD_CREATE_SEC_CPU = 4, 51 BIT_UVC_CMD_DESTROY_SEC_CPU = 5, 52 BIT_UVC_CMD_CONV_TO_SEC_STOR = 6, 53 BIT_UVC_CMD_CONV_FROM_SEC_STOR = 7, 54 BIT_UVC_CMD_SET_SHARED_ACCESS = 8, 55 BIT_UVC_CMD_REMOVE_SHARED_ACCESS = 9, 56 BIT_UVC_CMD_SET_SEC_PARMS = 11, 57 BIT_UVC_CMD_UNPACK_IMG = 13, 58 BIT_UVC_CMD_VERIFY_IMG = 14, 59 BIT_UVC_CMD_PIN_PAGE_SHARED = 21, 60 BIT_UVC_CMD_UNPIN_PAGE_SHARED = 22, 61 }; 62 63 struct uv_cb_header { 64 u16 len; 65 u16 cmd; /* Command Code */ 66 u16 rc; /* Response Code */ 67 u16 rrc; /* Return Reason Code */ 68 } __packed __aligned(8); 69 70 /* Query Ultravisor Information */ 71 struct uv_cb_qui { 72 struct uv_cb_header header; 73 u64 reserved08; 74 u64 inst_calls_list[4]; 75 u64 reserved30[2]; 76 u64 uv_base_stor_len; 77 u64 reserved48; 78 u64 conf_base_phys_stor_len; 79 u64 conf_base_virt_stor_len; 80 u64 conf_virt_var_stor_len; 81 u64 cpu_stor_len; 82 u32 reserved70[3]; 83 u32 max_num_sec_conf; 84 u64 max_guest_stor_addr; 85 u8 reserved88[158 - 136]; 86 u16 max_guest_cpus; 87 u8 reserveda0[200 - 160]; 88 } __packed __aligned(8); 89 90 /* Initialize Ultravisor */ 91 struct uv_cb_init { 92 struct uv_cb_header header; 93 u64 reserved08[2]; 94 u64 stor_origin; 95 u64 stor_len; 96 u64 reserved28[4]; 97 } __packed __aligned(8); 98 99 /* Create Guest Configuration */ 100 struct uv_cb_cgc { 101 struct uv_cb_header header; 102 u64 reserved08[2]; 103 u64 guest_handle; 104 u64 conf_base_stor_origin; 105 u64 conf_virt_stor_origin; 106 u64 reserved30; 107 u64 guest_stor_origin; 108 u64 guest_stor_len; 109 u64 guest_sca; 110 u64 guest_asce; 111 u64 reserved58[5]; 112 } __packed __aligned(8); 113 114 /* Create Secure CPU */ 115 struct uv_cb_csc { 116 struct uv_cb_header header; 117 u64 reserved08[2]; 118 u64 cpu_handle; 119 u64 guest_handle; 120 u64 stor_origin; 121 u8 reserved30[6]; 122 u16 num; 123 u64 state_origin; 124 u64 reserved40[4]; 125 } __packed __aligned(8); 126 127 /* Convert to Secure */ 128 struct uv_cb_cts { 129 struct uv_cb_header header; 130 u64 reserved08[2]; 131 u64 guest_handle; 132 u64 gaddr; 133 } __packed __aligned(8); 134 135 /* Convert from Secure / Pin Page Shared */ 136 struct uv_cb_cfs { 137 struct uv_cb_header header; 138 u64 reserved08[2]; 139 u64 paddr; 140 } __packed __aligned(8); 141 142 /* Set Secure Config Parameter */ 143 struct uv_cb_ssc { 144 struct uv_cb_header header; 145 u64 reserved08[2]; 146 u64 guest_handle; 147 u64 sec_header_origin; 148 u32 sec_header_len; 149 u32 reserved2c; 150 u64 reserved30[4]; 151 } __packed __aligned(8); 152 153 /* Unpack */ 154 struct uv_cb_unp { 155 struct uv_cb_header header; 156 u64 reserved08[2]; 157 u64 guest_handle; 158 u64 gaddr; 159 u64 tweak[2]; 160 u64 reserved38[3]; 161 } __packed __aligned(8); 162 163 /* 164 * A common UV call struct for calls that take no payload 165 * Examples: 166 * Destroy cpu/config 167 * Verify 168 */ 169 struct uv_cb_nodata { 170 struct uv_cb_header header; 171 u64 reserved08[2]; 172 u64 handle; 173 u64 reserved20[4]; 174 } __packed __aligned(8); 175 176 /* Set Shared Access */ 177 struct uv_cb_share { 178 struct uv_cb_header header; 179 u64 reserved08[3]; 180 u64 paddr; 181 u64 reserved28; 182 } __packed __aligned(8); 183 184 static inline int __uv_call(unsigned long r1, unsigned long r2) 185 { 186 int cc; 187 188 asm volatile( 189 " .insn rrf,0xB9A40000,%[r1],%[r2],0,0\n" 190 " ipm %[cc]\n" 191 " srl %[cc],28\n" 192 : [cc] "=d" (cc) 193 : [r1] "a" (r1), [r2] "a" (r2) 194 : "memory", "cc"); 195 return cc; 196 } 197 198 static inline int uv_call(unsigned long r1, unsigned long r2) 199 { 200 int cc; 201 202 do { 203 cc = __uv_call(r1, r2); 204 } while (cc > 1); 205 return cc; 206 } 207 208 /* Low level uv_call that avoids stalls for long running busy conditions */ 209 static inline int uv_call_sched(unsigned long r1, unsigned long r2) 210 { 211 int cc; 212 213 do { 214 cc = __uv_call(r1, r2); 215 cond_resched(); 216 } while (cc > 1); 217 return cc; 218 } 219 220 /* 221 * special variant of uv_call that only transports the cpu or guest 222 * handle and the command, like destroy or verify. 223 */ 224 static inline int uv_cmd_nodata(u64 handle, u16 cmd, u16 *rc, u16 *rrc) 225 { 226 struct uv_cb_nodata uvcb = { 227 .header.cmd = cmd, 228 .header.len = sizeof(uvcb), 229 .handle = handle, 230 }; 231 int cc; 232 233 WARN(!handle, "No handle provided to Ultravisor call cmd %x\n", cmd); 234 cc = uv_call_sched(0, (u64)&uvcb); 235 *rc = uvcb.header.rc; 236 *rrc = uvcb.header.rrc; 237 return cc ? -EINVAL : 0; 238 } 239 240 struct uv_info { 241 unsigned long inst_calls_list[4]; 242 unsigned long uv_base_stor_len; 243 unsigned long guest_base_stor_len; 244 unsigned long guest_virt_base_stor_len; 245 unsigned long guest_virt_var_stor_len; 246 unsigned long guest_cpu_stor_len; 247 unsigned long max_sec_stor_addr; 248 unsigned int max_num_sec_conf; 249 unsigned short max_guest_cpus; 250 }; 251 252 extern struct uv_info uv_info; 253 254 #ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST 255 extern int prot_virt_guest; 256 257 static inline int is_prot_virt_guest(void) 258 { 259 return prot_virt_guest; 260 } 261 262 static inline int share(unsigned long addr, u16 cmd) 263 { 264 struct uv_cb_share uvcb = { 265 .header.cmd = cmd, 266 .header.len = sizeof(uvcb), 267 .paddr = addr 268 }; 269 270 if (!is_prot_virt_guest()) 271 return -EOPNOTSUPP; 272 /* 273 * Sharing is page wise, if we encounter addresses that are 274 * not page aligned, we assume something went wrong. If 275 * malloced structs are passed to this function, we could leak 276 * data to the hypervisor. 277 */ 278 BUG_ON(addr & ~PAGE_MASK); 279 280 if (!uv_call(0, (u64)&uvcb)) 281 return 0; 282 return -EINVAL; 283 } 284 285 /* 286 * Guest 2 request to the Ultravisor to make a page shared with the 287 * hypervisor for IO. 288 * 289 * @addr: Real or absolute address of the page to be shared 290 */ 291 static inline int uv_set_shared(unsigned long addr) 292 { 293 return share(addr, UVC_CMD_SET_SHARED_ACCESS); 294 } 295 296 /* 297 * Guest 2 request to the Ultravisor to make a page unshared. 298 * 299 * @addr: Real or absolute address of the page to be unshared 300 */ 301 static inline int uv_remove_shared(unsigned long addr) 302 { 303 return share(addr, UVC_CMD_REMOVE_SHARED_ACCESS); 304 } 305 306 #else 307 #define is_prot_virt_guest() 0 308 static inline int uv_set_shared(unsigned long addr) { return 0; } 309 static inline int uv_remove_shared(unsigned long addr) { return 0; } 310 #endif 311 312 #if IS_ENABLED(CONFIG_KVM) 313 extern int prot_virt_host; 314 315 static inline int is_prot_virt_host(void) 316 { 317 return prot_virt_host; 318 } 319 320 int gmap_make_secure(struct gmap *gmap, unsigned long gaddr, void *uvcb); 321 int uv_convert_from_secure(unsigned long paddr); 322 int gmap_convert_to_secure(struct gmap *gmap, unsigned long gaddr); 323 324 void setup_uv(void); 325 void adjust_to_uv_max(unsigned long *vmax); 326 #else 327 #define is_prot_virt_host() 0 328 static inline void setup_uv(void) {} 329 static inline void adjust_to_uv_max(unsigned long *vmax) {} 330 331 static inline int uv_convert_from_secure(unsigned long paddr) 332 { 333 return 0; 334 } 335 #endif 336 337 #if defined(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) || IS_ENABLED(CONFIG_KVM) 338 void uv_query_info(void); 339 #else 340 static inline void uv_query_info(void) {} 341 #endif 342 343 #endif /* _ASM_S390_UV_H */ 344