Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Ultravisor Interfaces
0004  *
0005  * Copyright IBM Corp. 2019, 2022
0006  *
0007  * Author(s):
0008  *  Vasily Gorbik <gor@linux.ibm.com>
0009  *  Janosch Frank <frankja@linux.ibm.com>
0010  */
0011 #ifndef _ASM_S390_UV_H
0012 #define _ASM_S390_UV_H
0013 
0014 #include <linux/types.h>
0015 #include <linux/errno.h>
0016 #include <linux/bug.h>
0017 #include <linux/sched.h>
0018 #include <asm/page.h>
0019 #include <asm/gmap.h>
0020 
0021 #define UVC_CC_OK   0
0022 #define UVC_CC_ERROR    1
0023 #define UVC_CC_BUSY 2
0024 #define UVC_CC_PARTIAL  3
0025 
0026 #define UVC_RC_EXECUTED     0x0001
0027 #define UVC_RC_INV_CMD      0x0002
0028 #define UVC_RC_INV_STATE    0x0003
0029 #define UVC_RC_INV_LEN      0x0005
0030 #define UVC_RC_NO_RESUME    0x0007
0031 #define UVC_RC_NEED_DESTROY 0x8000
0032 
0033 #define UVC_CMD_QUI         0x0001
0034 #define UVC_CMD_INIT_UV         0x000f
0035 #define UVC_CMD_CREATE_SEC_CONF     0x0100
0036 #define UVC_CMD_DESTROY_SEC_CONF    0x0101
0037 #define UVC_CMD_CREATE_SEC_CPU      0x0120
0038 #define UVC_CMD_DESTROY_SEC_CPU     0x0121
0039 #define UVC_CMD_CONV_TO_SEC_STOR    0x0200
0040 #define UVC_CMD_CONV_FROM_SEC_STOR  0x0201
0041 #define UVC_CMD_DESTR_SEC_STOR      0x0202
0042 #define UVC_CMD_SET_SEC_CONF_PARAMS 0x0300
0043 #define UVC_CMD_UNPACK_IMG      0x0301
0044 #define UVC_CMD_VERIFY_IMG      0x0302
0045 #define UVC_CMD_CPU_RESET       0x0310
0046 #define UVC_CMD_CPU_RESET_INITIAL   0x0311
0047 #define UVC_CMD_PREPARE_RESET       0x0320
0048 #define UVC_CMD_CPU_RESET_CLEAR     0x0321
0049 #define UVC_CMD_CPU_SET_STATE       0x0330
0050 #define UVC_CMD_SET_UNSHARE_ALL     0x0340
0051 #define UVC_CMD_PIN_PAGE_SHARED     0x0341
0052 #define UVC_CMD_UNPIN_PAGE_SHARED   0x0342
0053 #define UVC_CMD_DUMP_INIT       0x0400
0054 #define UVC_CMD_DUMP_CONF_STOR_STATE    0x0401
0055 #define UVC_CMD_DUMP_CPU        0x0402
0056 #define UVC_CMD_DUMP_COMPLETE       0x0403
0057 #define UVC_CMD_SET_SHARED_ACCESS   0x1000
0058 #define UVC_CMD_REMOVE_SHARED_ACCESS    0x1001
0059 #define UVC_CMD_RETR_ATTEST     0x1020
0060 
0061 /* Bits in installed uv calls */
0062 enum uv_cmds_inst {
0063     BIT_UVC_CMD_QUI = 0,
0064     BIT_UVC_CMD_INIT_UV = 1,
0065     BIT_UVC_CMD_CREATE_SEC_CONF = 2,
0066     BIT_UVC_CMD_DESTROY_SEC_CONF = 3,
0067     BIT_UVC_CMD_CREATE_SEC_CPU = 4,
0068     BIT_UVC_CMD_DESTROY_SEC_CPU = 5,
0069     BIT_UVC_CMD_CONV_TO_SEC_STOR = 6,
0070     BIT_UVC_CMD_CONV_FROM_SEC_STOR = 7,
0071     BIT_UVC_CMD_SET_SHARED_ACCESS = 8,
0072     BIT_UVC_CMD_REMOVE_SHARED_ACCESS = 9,
0073     BIT_UVC_CMD_SET_SEC_PARMS = 11,
0074     BIT_UVC_CMD_UNPACK_IMG = 13,
0075     BIT_UVC_CMD_VERIFY_IMG = 14,
0076     BIT_UVC_CMD_CPU_RESET = 15,
0077     BIT_UVC_CMD_CPU_RESET_INITIAL = 16,
0078     BIT_UVC_CMD_CPU_SET_STATE = 17,
0079     BIT_UVC_CMD_PREPARE_RESET = 18,
0080     BIT_UVC_CMD_CPU_PERFORM_CLEAR_RESET = 19,
0081     BIT_UVC_CMD_UNSHARE_ALL = 20,
0082     BIT_UVC_CMD_PIN_PAGE_SHARED = 21,
0083     BIT_UVC_CMD_UNPIN_PAGE_SHARED = 22,
0084     BIT_UVC_CMD_DUMP_INIT = 24,
0085     BIT_UVC_CMD_DUMP_CONFIG_STOR_STATE = 25,
0086     BIT_UVC_CMD_DUMP_CPU = 26,
0087     BIT_UVC_CMD_DUMP_COMPLETE = 27,
0088     BIT_UVC_CMD_RETR_ATTEST = 28,
0089 };
0090 
0091 enum uv_feat_ind {
0092     BIT_UV_FEAT_MISC = 0,
0093     BIT_UV_FEAT_AIV = 1,
0094 };
0095 
0096 struct uv_cb_header {
0097     u16 len;
0098     u16 cmd;    /* Command Code */
0099     u16 rc;     /* Response Code */
0100     u16 rrc;    /* Return Reason Code */
0101 } __packed __aligned(8);
0102 
0103 /* Query Ultravisor Information */
0104 struct uv_cb_qui {
0105     struct uv_cb_header header;     /* 0x0000 */
0106     u64 reserved08;             /* 0x0008 */
0107     u64 inst_calls_list[4];         /* 0x0010 */
0108     u64 reserved30[2];          /* 0x0030 */
0109     u64 uv_base_stor_len;           /* 0x0040 */
0110     u64 reserved48;             /* 0x0048 */
0111     u64 conf_base_phys_stor_len;        /* 0x0050 */
0112     u64 conf_base_virt_stor_len;        /* 0x0058 */
0113     u64 conf_virt_var_stor_len;     /* 0x0060 */
0114     u64 cpu_stor_len;           /* 0x0068 */
0115     u32 reserved70[3];          /* 0x0070 */
0116     u32 max_num_sec_conf;           /* 0x007c */
0117     u64 max_guest_stor_addr;        /* 0x0080 */
0118     u8  reserved88[158 - 136];      /* 0x0088 */
0119     u16 max_guest_cpu_id;           /* 0x009e */
0120     u64 uv_feature_indications;     /* 0x00a0 */
0121     u64 reserveda8;             /* 0x00a8 */
0122     u64 supp_se_hdr_versions;       /* 0x00b0 */
0123     u64 supp_se_hdr_pcf;            /* 0x00b8 */
0124     u64 reservedc0;             /* 0x00c0 */
0125     u64 conf_dump_storage_state_len;    /* 0x00c8 */
0126     u64 conf_dump_finalize_len;     /* 0x00d0 */
0127     u64 reservedd8;             /* 0x00d8 */
0128     u64 supp_att_req_hdr_ver;       /* 0x00e0 */
0129     u64 supp_att_pflags;            /* 0x00e8 */
0130     u8 reservedf0[256 - 240];       /* 0x00f0 */
0131 } __packed __aligned(8);
0132 
0133 /* Initialize Ultravisor */
0134 struct uv_cb_init {
0135     struct uv_cb_header header;
0136     u64 reserved08[2];
0137     u64 stor_origin;
0138     u64 stor_len;
0139     u64 reserved28[4];
0140 } __packed __aligned(8);
0141 
0142 /* Create Guest Configuration */
0143 struct uv_cb_cgc {
0144     struct uv_cb_header header;
0145     u64 reserved08[2];
0146     u64 guest_handle;
0147     u64 conf_base_stor_origin;
0148     u64 conf_virt_stor_origin;
0149     u64 reserved30;
0150     u64 guest_stor_origin;
0151     u64 guest_stor_len;
0152     u64 guest_sca;
0153     u64 guest_asce;
0154     u64 reserved58[5];
0155 } __packed __aligned(8);
0156 
0157 /* Create Secure CPU */
0158 struct uv_cb_csc {
0159     struct uv_cb_header header;
0160     u64 reserved08[2];
0161     u64 cpu_handle;
0162     u64 guest_handle;
0163     u64 stor_origin;
0164     u8  reserved30[6];
0165     u16 num;
0166     u64 state_origin;
0167     u64 reserved40[4];
0168 } __packed __aligned(8);
0169 
0170 /* Convert to Secure */
0171 struct uv_cb_cts {
0172     struct uv_cb_header header;
0173     u64 reserved08[2];
0174     u64 guest_handle;
0175     u64 gaddr;
0176 } __packed __aligned(8);
0177 
0178 /* Convert from Secure / Pin Page Shared */
0179 struct uv_cb_cfs {
0180     struct uv_cb_header header;
0181     u64 reserved08[2];
0182     u64 paddr;
0183 } __packed __aligned(8);
0184 
0185 /* Set Secure Config Parameter */
0186 struct uv_cb_ssc {
0187     struct uv_cb_header header;
0188     u64 reserved08[2];
0189     u64 guest_handle;
0190     u64 sec_header_origin;
0191     u32 sec_header_len;
0192     u32 reserved2c;
0193     u64 reserved30[4];
0194 } __packed __aligned(8);
0195 
0196 /* Unpack */
0197 struct uv_cb_unp {
0198     struct uv_cb_header header;
0199     u64 reserved08[2];
0200     u64 guest_handle;
0201     u64 gaddr;
0202     u64 tweak[2];
0203     u64 reserved38[3];
0204 } __packed __aligned(8);
0205 
0206 #define PV_CPU_STATE_OPR    1
0207 #define PV_CPU_STATE_STP    2
0208 #define PV_CPU_STATE_CHKSTP 3
0209 #define PV_CPU_STATE_OPR_LOAD   5
0210 
0211 struct uv_cb_cpu_set_state {
0212     struct uv_cb_header header;
0213     u64 reserved08[2];
0214     u64 cpu_handle;
0215     u8  reserved20[7];
0216     u8  state;
0217     u64 reserved28[5];
0218 };
0219 
0220 /*
0221  * A common UV call struct for calls that take no payload
0222  * Examples:
0223  * Destroy cpu/config
0224  * Verify
0225  */
0226 struct uv_cb_nodata {
0227     struct uv_cb_header header;
0228     u64 reserved08[2];
0229     u64 handle;
0230     u64 reserved20[4];
0231 } __packed __aligned(8);
0232 
0233 /* Set Shared Access */
0234 struct uv_cb_share {
0235     struct uv_cb_header header;
0236     u64 reserved08[3];
0237     u64 paddr;
0238     u64 reserved28;
0239 } __packed __aligned(8);
0240 
0241 /* Retrieve Attestation Measurement */
0242 struct uv_cb_attest {
0243     struct uv_cb_header header; /* 0x0000 */
0244     u64 reserved08[2];      /* 0x0008 */
0245     u64 arcb_addr;          /* 0x0018 */
0246     u64 cont_token;         /* 0x0020 */
0247     u8  reserved28[6];      /* 0x0028 */
0248     u16 user_data_len;      /* 0x002e */
0249     u8  user_data[256];     /* 0x0030 */
0250     u32 reserved130[3];     /* 0x0130 */
0251     u32 meas_len;           /* 0x013c */
0252     u64 meas_addr;          /* 0x0140 */
0253     u8  config_uid[16];     /* 0x0148 */
0254     u32 reserved158;        /* 0x0158 */
0255     u32 add_data_len;       /* 0x015c */
0256     u64 add_data_addr;      /* 0x0160 */
0257     u64 reserved168[4];     /* 0x0168 */
0258 } __packed __aligned(8);
0259 
0260 struct uv_cb_dump_cpu {
0261     struct uv_cb_header header;
0262     u64 reserved08[2];
0263     u64 cpu_handle;
0264     u64 dump_area_origin;
0265     u64 reserved28[5];
0266 } __packed __aligned(8);
0267 
0268 struct uv_cb_dump_stor_state {
0269     struct uv_cb_header header;
0270     u64 reserved08[2];
0271     u64 config_handle;
0272     u64 dump_area_origin;
0273     u64 gaddr;
0274     u64 reserved28[4];
0275 } __packed __aligned(8);
0276 
0277 struct uv_cb_dump_complete {
0278     struct uv_cb_header header;
0279     u64 reserved08[2];
0280     u64 config_handle;
0281     u64 dump_area_origin;
0282     u64 reserved30[5];
0283 } __packed __aligned(8);
0284 
0285 static inline int __uv_call(unsigned long r1, unsigned long r2)
0286 {
0287     int cc;
0288 
0289     asm volatile(
0290         "   .insn rrf,0xB9A40000,%[r1],%[r2],0,0\n"
0291         "   ipm %[cc]\n"
0292         "   srl %[cc],28\n"
0293         : [cc] "=d" (cc)
0294         : [r1] "a" (r1), [r2] "a" (r2)
0295         : "memory", "cc");
0296     return cc;
0297 }
0298 
0299 static inline int uv_call(unsigned long r1, unsigned long r2)
0300 {
0301     int cc;
0302 
0303     do {
0304         cc = __uv_call(r1, r2);
0305     } while (cc > 1);
0306     return cc;
0307 }
0308 
0309 /* Low level uv_call that avoids stalls for long running busy conditions  */
0310 static inline int uv_call_sched(unsigned long r1, unsigned long r2)
0311 {
0312     int cc;
0313 
0314     do {
0315         cc = __uv_call(r1, r2);
0316         cond_resched();
0317     } while (cc > 1);
0318     return cc;
0319 }
0320 
0321 /*
0322  * special variant of uv_call that only transports the cpu or guest
0323  * handle and the command, like destroy or verify.
0324  */
0325 static inline int uv_cmd_nodata(u64 handle, u16 cmd, u16 *rc, u16 *rrc)
0326 {
0327     struct uv_cb_nodata uvcb = {
0328         .header.cmd = cmd,
0329         .header.len = sizeof(uvcb),
0330         .handle = handle,
0331     };
0332     int cc;
0333 
0334     WARN(!handle, "No handle provided to Ultravisor call cmd %x\n", cmd);
0335     cc = uv_call_sched(0, (u64)&uvcb);
0336     *rc = uvcb.header.rc;
0337     *rrc = uvcb.header.rrc;
0338     return cc ? -EINVAL : 0;
0339 }
0340 
0341 struct uv_info {
0342     unsigned long inst_calls_list[4];
0343     unsigned long uv_base_stor_len;
0344     unsigned long guest_base_stor_len;
0345     unsigned long guest_virt_base_stor_len;
0346     unsigned long guest_virt_var_stor_len;
0347     unsigned long guest_cpu_stor_len;
0348     unsigned long max_sec_stor_addr;
0349     unsigned int max_num_sec_conf;
0350     unsigned short max_guest_cpu_id;
0351     unsigned long uv_feature_indications;
0352     unsigned long supp_se_hdr_ver;
0353     unsigned long supp_se_hdr_pcf;
0354     unsigned long conf_dump_storage_state_len;
0355     unsigned long conf_dump_finalize_len;
0356     unsigned long supp_att_req_hdr_ver;
0357     unsigned long supp_att_pflags;
0358 };
0359 
0360 extern struct uv_info uv_info;
0361 
0362 #ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
0363 extern int prot_virt_guest;
0364 
0365 static inline int is_prot_virt_guest(void)
0366 {
0367     return prot_virt_guest;
0368 }
0369 
0370 static inline int share(unsigned long addr, u16 cmd)
0371 {
0372     struct uv_cb_share uvcb = {
0373         .header.cmd = cmd,
0374         .header.len = sizeof(uvcb),
0375         .paddr = addr
0376     };
0377 
0378     if (!is_prot_virt_guest())
0379         return -EOPNOTSUPP;
0380     /*
0381      * Sharing is page wise, if we encounter addresses that are
0382      * not page aligned, we assume something went wrong. If
0383      * malloced structs are passed to this function, we could leak
0384      * data to the hypervisor.
0385      */
0386     BUG_ON(addr & ~PAGE_MASK);
0387 
0388     if (!uv_call(0, (u64)&uvcb))
0389         return 0;
0390     return -EINVAL;
0391 }
0392 
0393 /*
0394  * Guest 2 request to the Ultravisor to make a page shared with the
0395  * hypervisor for IO.
0396  *
0397  * @addr: Real or absolute address of the page to be shared
0398  */
0399 static inline int uv_set_shared(unsigned long addr)
0400 {
0401     return share(addr, UVC_CMD_SET_SHARED_ACCESS);
0402 }
0403 
0404 /*
0405  * Guest 2 request to the Ultravisor to make a page unshared.
0406  *
0407  * @addr: Real or absolute address of the page to be unshared
0408  */
0409 static inline int uv_remove_shared(unsigned long addr)
0410 {
0411     return share(addr, UVC_CMD_REMOVE_SHARED_ACCESS);
0412 }
0413 
0414 #else
0415 #define is_prot_virt_guest() 0
0416 static inline int uv_set_shared(unsigned long addr) { return 0; }
0417 static inline int uv_remove_shared(unsigned long addr) { return 0; }
0418 #endif
0419 
0420 #if IS_ENABLED(CONFIG_KVM)
0421 extern int prot_virt_host;
0422 
0423 static inline int is_prot_virt_host(void)
0424 {
0425     return prot_virt_host;
0426 }
0427 
0428 int gmap_make_secure(struct gmap *gmap, unsigned long gaddr, void *uvcb);
0429 int gmap_destroy_page(struct gmap *gmap, unsigned long gaddr);
0430 int uv_destroy_owned_page(unsigned long paddr);
0431 int uv_convert_from_secure(unsigned long paddr);
0432 int uv_convert_owned_from_secure(unsigned long paddr);
0433 int gmap_convert_to_secure(struct gmap *gmap, unsigned long gaddr);
0434 
0435 void setup_uv(void);
0436 #else
0437 #define is_prot_virt_host() 0
0438 static inline void setup_uv(void) {}
0439 
0440 static inline int uv_destroy_owned_page(unsigned long paddr)
0441 {
0442     return 0;
0443 }
0444 
0445 static inline int uv_convert_from_secure(unsigned long paddr)
0446 {
0447     return 0;
0448 }
0449 
0450 static inline int uv_convert_owned_from_secure(unsigned long paddr)
0451 {
0452     return 0;
0453 }
0454 #endif
0455 
0456 #endif /* _ASM_S390_UV_H */