12ea7afb6SJanosch Frank /* 22ea7afb6SJanosch Frank * s390x Ultravisor related definitions 32ea7afb6SJanosch Frank * 42ea7afb6SJanosch Frank * Copyright (c) 2020 IBM Corp 52ea7afb6SJanosch Frank * 62ea7afb6SJanosch Frank * Authors: 72ea7afb6SJanosch Frank * Janosch Frank <frankja@linux.ibm.com> 82ea7afb6SJanosch Frank * 92ea7afb6SJanosch Frank * This code is free software; you can redistribute it and/or modify it 102ea7afb6SJanosch Frank * under the terms of the GNU General Public License version 2. 112ea7afb6SJanosch Frank */ 12eb5a1bbaSCornelia Huck #ifndef _ASMS390X_UV_H_ 13eb5a1bbaSCornelia Huck #define _ASMS390X_UV_H_ 142ea7afb6SJanosch Frank 15*04bf4919SJanosch Frank /* Enables printing of command code and return codes for failed UVCs */ 16*04bf4919SJanosch Frank #ifndef UVC_ERR_DEBUG 17*04bf4919SJanosch Frank #define UVC_ERR_DEBUG 0 18*04bf4919SJanosch Frank #endif 19*04bf4919SJanosch Frank 202ea7afb6SJanosch Frank #define UVC_RC_EXECUTED 0x0001 212ea7afb6SJanosch Frank #define UVC_RC_INV_CMD 0x0002 222ea7afb6SJanosch Frank #define UVC_RC_INV_STATE 0x0003 232ea7afb6SJanosch Frank #define UVC_RC_INV_LEN 0x0005 242ea7afb6SJanosch Frank #define UVC_RC_NO_RESUME 0x0007 2583d815a2SJanosch Frank #define UVC_RC_INV_GHANDLE 0x0020 2683d815a2SJanosch Frank #define UVC_RC_INV_CHANDLE 0x0021 272ea7afb6SJanosch Frank 282ea7afb6SJanosch Frank #define UVC_CMD_QUI 0x0001 2983d815a2SJanosch Frank #define UVC_CMD_INIT_UV 0x000f 3083d815a2SJanosch Frank #define UVC_CMD_CREATE_SEC_CONF 0x0100 3183d815a2SJanosch Frank #define UVC_CMD_DESTROY_SEC_CONF 0x0101 3283d815a2SJanosch Frank #define UVC_CMD_CREATE_SEC_CPU 0x0120 3383d815a2SJanosch Frank #define UVC_CMD_DESTROY_SEC_CPU 0x0121 3483d815a2SJanosch Frank #define UVC_CMD_CONV_TO_SEC_STOR 0x0200 3583d815a2SJanosch Frank #define UVC_CMD_CONV_FROM_SEC_STOR 0x0201 3683d815a2SJanosch Frank #define UVC_CMD_SET_SEC_CONF_PARAMS 0x0300 3783d815a2SJanosch Frank #define UVC_CMD_UNPACK_IMG 0x0301 3883d815a2SJanosch Frank #define UVC_CMD_VERIFY_IMG 0x0302 3983d815a2SJanosch Frank #define UVC_CMD_CPU_RESET 0x0310 4083d815a2SJanosch Frank #define UVC_CMD_CPU_RESET_INITIAL 0x0311 4183d815a2SJanosch Frank #define UVC_CMD_PERF_CONF_CLEAR_RESET 0x0320 4283d815a2SJanosch Frank #define UVC_CMD_CPU_RESET_CLEAR 0x0321 4383d815a2SJanosch Frank #define UVC_CMD_CPU_SET_STATE 0x0330 4483d815a2SJanosch Frank #define UVC_CMD_SET_UNSHARED_ALL 0x0340 4583d815a2SJanosch Frank #define UVC_CMD_PIN_PAGE_SHARED 0x0341 4683d815a2SJanosch Frank #define UVC_CMD_UNPIN_PAGE_SHARED 0x0342 472ea7afb6SJanosch Frank #define UVC_CMD_SET_SHARED_ACCESS 0x1000 482ea7afb6SJanosch Frank #define UVC_CMD_REMOVE_SHARED_ACCESS 0x1001 492ea7afb6SJanosch Frank 502ea7afb6SJanosch Frank /* Bits in installed uv calls */ 512ea7afb6SJanosch Frank enum uv_cmds_inst { 522ea7afb6SJanosch Frank BIT_UVC_CMD_QUI = 0, 5383d815a2SJanosch Frank BIT_UVC_CMD_INIT_UV = 1, 5483d815a2SJanosch Frank BIT_UVC_CMD_CREATE_SEC_CONF = 2, 5583d815a2SJanosch Frank BIT_UVC_CMD_DESTROY_SEC_CONF = 3, 5683d815a2SJanosch Frank BIT_UVC_CMD_CREATE_SEC_CPU = 4, 5783d815a2SJanosch Frank BIT_UVC_CMD_DESTROY_SEC_CPU = 5, 5883d815a2SJanosch Frank BIT_UVC_CMD_CONV_TO_SEC_STOR = 6, 5983d815a2SJanosch Frank BIT_UVC_CMD_CONV_FROM_SEC_STOR = 7, 602ea7afb6SJanosch Frank BIT_UVC_CMD_SET_SHARED_ACCESS = 8, 612ea7afb6SJanosch Frank BIT_UVC_CMD_REMOVE_SHARED_ACCESS = 9, 6283d815a2SJanosch Frank BIT_UVC_CMD_SET_SEC_PARMS = 11, 6383d815a2SJanosch Frank BIT_UVC_CMD_UNPACK_IMG = 13, 6483d815a2SJanosch Frank BIT_UVC_CMD_VERIFY_IMG = 14, 6583d815a2SJanosch Frank BIT_UVC_CMD_CPU_RESET = 15, 6683d815a2SJanosch Frank BIT_UVC_CMD_CPU_RESET_INITIAL = 16, 6783d815a2SJanosch Frank BIT_UVC_CMD_CPU_SET_STATE = 17, 6883d815a2SJanosch Frank BIT_UVC_CMD_PREPARE_CLEAR_RESET = 18, 6983d815a2SJanosch Frank BIT_UVC_CMD_CPU_PERFORM_CLEAR_RESET = 19, 7083d815a2SJanosch Frank BIT_UVC_CMD_UNSHARE_ALL = 20, 7183d815a2SJanosch Frank BIT_UVC_CMD_PIN_PAGE_SHARED = 21, 7283d815a2SJanosch Frank BIT_UVC_CMD_UNPIN_PAGE_SHARED = 22, 732ea7afb6SJanosch Frank }; 742ea7afb6SJanosch Frank 752ea7afb6SJanosch Frank struct uv_cb_header { 762ea7afb6SJanosch Frank u16 len; 772ea7afb6SJanosch Frank u16 cmd; /* Command Code */ 782ea7afb6SJanosch Frank u16 rc; /* Response Code */ 792ea7afb6SJanosch Frank u16 rrc; /* Return Reason Code */ 802ea7afb6SJanosch Frank } __attribute__((packed)) __attribute__((aligned(8))); 812ea7afb6SJanosch Frank 8283d815a2SJanosch Frank struct uv_cb_init { 8383d815a2SJanosch Frank struct uv_cb_header header; 8483d815a2SJanosch Frank u64 reserved08[2]; 8583d815a2SJanosch Frank u64 stor_origin; 8683d815a2SJanosch Frank u64 stor_len; 8783d815a2SJanosch Frank u64 reserved28[4]; 8883d815a2SJanosch Frank 8983d815a2SJanosch Frank } __attribute__((packed)) __attribute__((aligned(8))); 9083d815a2SJanosch Frank 912ea7afb6SJanosch Frank struct uv_cb_qui { 928b3403a1SJanosch Frank struct uv_cb_header header; /* 0x0000 */ 938b3403a1SJanosch Frank u64 reserved08; /* 0x0008 */ 948b3403a1SJanosch Frank u64 inst_calls_list[4]; /* 0x0010 */ 958b3403a1SJanosch Frank u64 reserved30[2]; /* 0x0030 */ 968b3403a1SJanosch Frank u64 uv_base_stor_len; /* 0x0040 */ 978b3403a1SJanosch Frank u64 reserved48; /* 0x0048 */ 988b3403a1SJanosch Frank u64 conf_base_phys_stor_len; /* 0x0050 */ 998b3403a1SJanosch Frank u64 conf_base_virt_stor_len; /* 0x0058 */ 1008b3403a1SJanosch Frank u64 conf_virt_var_stor_len; /* 0x0060 */ 1018b3403a1SJanosch Frank u64 cpu_stor_len; /* 0x0068 */ 1028b3403a1SJanosch Frank u32 reserved70[3]; /* 0x0070 */ 1038b3403a1SJanosch Frank u32 max_num_sec_conf; /* 0x007c */ 1048b3403a1SJanosch Frank u64 max_guest_stor_addr; /* 0x0080 */ 1058b3403a1SJanosch Frank u8 reserved88[158 - 136]; /* 0x0088 */ 1068b3403a1SJanosch Frank uint16_t max_guest_cpus; /* 0x009e */ 1078b3403a1SJanosch Frank u64 uv_feature_indications; /* 0x00a0 */ 1088b3403a1SJanosch Frank u8 reserveda8[200 - 168]; /* 0x00a8 */ 10983d815a2SJanosch Frank } __attribute__((packed)) __attribute__((aligned(8))); 11083d815a2SJanosch Frank 11183d815a2SJanosch Frank struct uv_cb_cgc { 11283d815a2SJanosch Frank struct uv_cb_header header; 11383d815a2SJanosch Frank u64 reserved08[2]; 11483d815a2SJanosch Frank u64 guest_handle; 11583d815a2SJanosch Frank u64 conf_base_stor_origin; 11683d815a2SJanosch Frank u64 conf_var_stor_origin; 11783d815a2SJanosch Frank u64 reserved30; 11883d815a2SJanosch Frank u64 guest_stor_origin; 11983d815a2SJanosch Frank u64 guest_stor_len; 12083d815a2SJanosch Frank u64 guest_sca; 12183d815a2SJanosch Frank u64 guest_asce; 12283d815a2SJanosch Frank u64 reserved60[5]; 12383d815a2SJanosch Frank } __attribute__((packed)) __attribute__((aligned(8))); 12483d815a2SJanosch Frank 12583d815a2SJanosch Frank struct uv_cb_csc { 12683d815a2SJanosch Frank struct uv_cb_header header; 12783d815a2SJanosch Frank u64 reserved08[2]; 12883d815a2SJanosch Frank u64 cpu_handle; 12983d815a2SJanosch Frank u64 guest_handle; 13083d815a2SJanosch Frank u64 stor_origin; 13183d815a2SJanosch Frank u8 reserved30[6]; 13283d815a2SJanosch Frank u16 num; 13383d815a2SJanosch Frank u64 state_origin; 13483d815a2SJanosch Frank u64 reserved[4]; 13583d815a2SJanosch Frank } __attribute__((packed)) __attribute__((aligned(8))); 13683d815a2SJanosch Frank 13783d815a2SJanosch Frank struct uv_cb_unp { 13883d815a2SJanosch Frank struct uv_cb_header header; 13983d815a2SJanosch Frank u64 reserved08[2]; 14083d815a2SJanosch Frank u64 guest_handle; 14183d815a2SJanosch Frank u64 gaddr; 14283d815a2SJanosch Frank u64 tweak[2]; 14383d815a2SJanosch Frank u64 reserved38[3]; 14483d815a2SJanosch Frank } __attribute__((packed)) __attribute__((aligned(8))); 14583d815a2SJanosch Frank 14683d815a2SJanosch Frank /* 14783d815a2SJanosch Frank * A common UV call struct for the following calls: 14883d815a2SJanosch Frank * Destroy cpu/config 14983d815a2SJanosch Frank * Verify 15083d815a2SJanosch Frank */ 15183d815a2SJanosch Frank struct uv_cb_nodata { 15283d815a2SJanosch Frank struct uv_cb_header header; 15383d815a2SJanosch Frank u64 reserved08[2]; 15483d815a2SJanosch Frank u64 handle; 15583d815a2SJanosch Frank u64 reserved20[4]; 1562ea7afb6SJanosch Frank } __attribute__((packed)) __attribute__((aligned(8))); 1572ea7afb6SJanosch Frank 1582ea7afb6SJanosch Frank struct uv_cb_share { 1592ea7afb6SJanosch Frank struct uv_cb_header header; 1602ea7afb6SJanosch Frank u64 reserved08[3]; 1612ea7afb6SJanosch Frank u64 paddr; 1622ea7afb6SJanosch Frank u64 reserved28; 1632ea7afb6SJanosch Frank } __attribute__((packed)) __attribute__((aligned(8))); 1642ea7afb6SJanosch Frank 16583d815a2SJanosch Frank /* Convert to Secure */ 16683d815a2SJanosch Frank struct uv_cb_cts { 16783d815a2SJanosch Frank struct uv_cb_header header; 16883d815a2SJanosch Frank u64 reserved08[2]; 16983d815a2SJanosch Frank u64 guest_handle; 17083d815a2SJanosch Frank u64 gaddr; 17183d815a2SJanosch Frank } __attribute__((packed)) __attribute__((aligned(8))); 17283d815a2SJanosch Frank 17383d815a2SJanosch Frank /* Convert from Secure / Pin Page Shared */ 17483d815a2SJanosch Frank struct uv_cb_cfs { 17583d815a2SJanosch Frank struct uv_cb_header header; 17683d815a2SJanosch Frank u64 reserved08[2]; 17783d815a2SJanosch Frank u64 paddr; 17883d815a2SJanosch Frank } __attribute__((packed)) __attribute__((aligned(8))); 17983d815a2SJanosch Frank 18083d815a2SJanosch Frank /* Set Secure Config Parameter */ 18183d815a2SJanosch Frank struct uv_cb_ssc { 18283d815a2SJanosch Frank struct uv_cb_header header; 18383d815a2SJanosch Frank u64 reserved08[2]; 18483d815a2SJanosch Frank u64 guest_handle; 18583d815a2SJanosch Frank u64 sec_header_origin; 18683d815a2SJanosch Frank u32 sec_header_len; 18783d815a2SJanosch Frank u32 reserved2c; 18883d815a2SJanosch Frank u64 reserved30[4]; 18983d815a2SJanosch Frank } __attribute__((packed)) __attribute__((aligned(8))); 19083d815a2SJanosch Frank 19188fb0e5dSJanosch Frank static inline int uv_call_once(unsigned long r1, unsigned long r2) 1922ea7afb6SJanosch Frank { 1932ea7afb6SJanosch Frank int cc; 1942ea7afb6SJanosch Frank 1952ea7afb6SJanosch Frank asm volatile( 1962ea7afb6SJanosch Frank "0: .insn rrf,0xB9A40000,%[r1],%[r2],0,0\n" 1972ea7afb6SJanosch Frank " ipm %[cc]\n" 1982ea7afb6SJanosch Frank " srl %[cc],28\n" 1992ea7afb6SJanosch Frank : [cc] "=d" (cc) 2002ea7afb6SJanosch Frank : [r1] "a" (r1), [r2] "a" (r2) 2012ea7afb6SJanosch Frank : "memory", "cc"); 202*04bf4919SJanosch Frank 203*04bf4919SJanosch Frank if (UVC_ERR_DEBUG && cc == 1) 204*04bf4919SJanosch Frank printf("UV call error: call %x rc %x rrc %x\n", 205*04bf4919SJanosch Frank ((struct uv_cb_header *)r2)->cmd, 206*04bf4919SJanosch Frank ((struct uv_cb_header *)r2)->rc, 207*04bf4919SJanosch Frank ((struct uv_cb_header *)r2)->rrc); 208*04bf4919SJanosch Frank 2092ea7afb6SJanosch Frank return cc; 2102ea7afb6SJanosch Frank } 2112ea7afb6SJanosch Frank 21288fb0e5dSJanosch Frank static inline int uv_call(unsigned long r1, unsigned long r2) 21388fb0e5dSJanosch Frank { 21488fb0e5dSJanosch Frank int cc; 21588fb0e5dSJanosch Frank 21688fb0e5dSJanosch Frank /* 21788fb0e5dSJanosch Frank * CC 2 and 3 tell us to re-execute because the instruction 21888fb0e5dSJanosch Frank * hasn't yet finished. 21988fb0e5dSJanosch Frank */ 22088fb0e5dSJanosch Frank do { 22188fb0e5dSJanosch Frank cc = uv_call_once(r1, r2); 22288fb0e5dSJanosch Frank } while (cc > 1); 22388fb0e5dSJanosch Frank 22488fb0e5dSJanosch Frank return cc; 22588fb0e5dSJanosch Frank } 22688fb0e5dSJanosch Frank 227027c8015SPierre Morel static inline int share(unsigned long addr, u16 cmd) 228027c8015SPierre Morel { 229027c8015SPierre Morel struct uv_cb_share uvcb = { 230027c8015SPierre Morel .header.cmd = cmd, 231027c8015SPierre Morel .header.len = sizeof(uvcb), 232027c8015SPierre Morel .paddr = addr 233027c8015SPierre Morel }; 234027c8015SPierre Morel 235e55cd64aSJanosch Frank return uv_call(0, (u64)&uvcb); 236027c8015SPierre Morel } 237027c8015SPierre Morel 238027c8015SPierre Morel /* 239027c8015SPierre Morel * Guest 2 request to the Ultravisor to make a page shared with the 240027c8015SPierre Morel * hypervisor for IO. 241027c8015SPierre Morel * 242027c8015SPierre Morel * @addr: Real or absolute address of the page to be shared 243027c8015SPierre Morel */ 244027c8015SPierre Morel static inline int uv_set_shared(unsigned long addr) 245027c8015SPierre Morel { 246027c8015SPierre Morel return share(addr, UVC_CMD_SET_SHARED_ACCESS); 247027c8015SPierre Morel } 248027c8015SPierre Morel 249027c8015SPierre Morel /* 250027c8015SPierre Morel * Guest 2 request to the Ultravisor to make a page unshared. 251027c8015SPierre Morel * 252027c8015SPierre Morel * @addr: Real or absolute address of the page to be unshared 253027c8015SPierre Morel */ 254027c8015SPierre Morel static inline int uv_remove_shared(unsigned long addr) 255027c8015SPierre Morel { 256027c8015SPierre Morel return share(addr, UVC_CMD_REMOVE_SHARED_ACCESS); 257027c8015SPierre Morel } 258027c8015SPierre Morel 25983d815a2SJanosch Frank struct uv_cb_cpu_set_state { 26083d815a2SJanosch Frank struct uv_cb_header header; 26183d815a2SJanosch Frank u64 reserved08[2]; 26283d815a2SJanosch Frank u64 cpu_handle; 26383d815a2SJanosch Frank u8 reserved20[7]; 26483d815a2SJanosch Frank u8 state; 26583d815a2SJanosch Frank u64 reserved28[5]; 26683d815a2SJanosch Frank }; 26783d815a2SJanosch Frank 26883d815a2SJanosch Frank #define PV_CPU_STATE_OPR 1 26983d815a2SJanosch Frank #define PV_CPU_STATE_STP 2 27083d815a2SJanosch Frank #define PV_CPU_STATE_CHKSTP 3 27183d815a2SJanosch Frank #define PV_CPU_STATE_OPR_LOAD 5 27283d815a2SJanosch Frank 2732ea7afb6SJanosch Frank #endif 274