···3232 __u16 reserved136; /* 0x0136 */3333};34343535+/**3636+ * uvio_uvdev_info - Information of supported functions3737+ * @supp_uvio_cmds - supported IOCTLs by this device3838+ * @supp_uv_cmds - supported UVCs corresponding to the IOCTL3939+ *4040+ * UVIO request to get information about supported request types by this4141+ * uvdevice and the Ultravisor. Everything is output. Bits are in LSB04242+ * ordering. If the bit is set in both, @supp_uvio_cmds and @supp_uv_cmds, the4343+ * uvdevice and the Ultravisor support that call.4444+ *4545+ * Note that bit 0 (UVIO_IOCTL_UVDEV_INFO_NR) is always zero for `supp_uv_cmds`4646+ * as there is no corresponding UV-call.4747+ */4848+struct uvio_uvdev_info {4949+ /*5050+ * If bit `n` is set, this device supports the IOCTL with nr `n`.5151+ */5252+ __u64 supp_uvio_cmds;5353+ /*5454+ * If bit `n` is set, the Ultravisor(UV) supports the UV-call5555+ * corresponding to the IOCTL with nr `n` in the calling contextx (host5656+ * or guest). The value is only valid if the corresponding bit in5757+ * @supp_uvio_cmds is set as well.5858+ */5959+ __u64 supp_uv_cmds;6060+};6161+3562/*3663 * The following max values define an upper length for the IOCTL in/out buffers.3764 * However, they do not represent the maximum the Ultravisor allows which is···6942#define UVIO_ATT_ARCB_MAX_LEN 0x1000007043#define UVIO_ATT_MEASUREMENT_MAX_LEN 0x80007144#define UVIO_ATT_ADDITIONAL_MAX_LEN 0x80004545+#define UVIO_ADD_SECRET_MAX_LEN 0x1000004646+#define UVIO_LIST_SECRETS_LEN 0x100072477348#define UVIO_DEVICE_NAME "uv"7449#define UVIO_TYPE_UVC 'u'75507676-#define UVIO_IOCTL_ATT _IOWR(UVIO_TYPE_UVC, 0x01, struct uvio_ioctl_cb)5151+enum UVIO_IOCTL_NR {5252+ UVIO_IOCTL_UVDEV_INFO_NR = 0x00,5353+ UVIO_IOCTL_ATT_NR,5454+ UVIO_IOCTL_ADD_SECRET_NR,5555+ UVIO_IOCTL_LIST_SECRETS_NR,5656+ UVIO_IOCTL_LOCK_SECRETS_NR,5757+ /* must be the last entry */5858+ UVIO_IOCTL_NUM_IOCTLS5959+};6060+6161+#define UVIO_IOCTL(nr) _IOWR(UVIO_TYPE_UVC, nr, struct uvio_ioctl_cb)6262+#define UVIO_IOCTL_UVDEV_INFO UVIO_IOCTL(UVIO_IOCTL_UVDEV_INFO_NR)6363+#define UVIO_IOCTL_ATT UVIO_IOCTL(UVIO_IOCTL_ATT_NR)6464+#define UVIO_IOCTL_ADD_SECRET UVIO_IOCTL(UVIO_IOCTL_ADD_SECRET_NR)6565+#define UVIO_IOCTL_LIST_SECRETS UVIO_IOCTL(UVIO_IOCTL_LIST_SECRETS_NR)6666+#define UVIO_IOCTL_LOCK_SECRETS UVIO_IOCTL(UVIO_IOCTL_LOCK_SECRETS_NR)6767+6868+#define UVIO_SUPP_CALL(nr) (1ULL << (nr))6969+#define UVIO_SUPP_UDEV_INFO UVIO_SUPP_CALL(UVIO_IOCTL_UDEV_INFO_NR)7070+#define UVIO_SUPP_ATT UVIO_SUPP_CALL(UVIO_IOCTL_ATT_NR)7171+#define UVIO_SUPP_ADD_SECRET UVIO_SUPP_CALL(UVIO_IOCTL_ADD_SECRET_NR)7272+#define UVIO_SUPP_LIST_SECRETS UVIO_SUPP_CALL(UVIO_IOCTL_LIST_SECRETS_NR)7373+#define UVIO_SUPP_LOCK_SECRETS UVIO_SUPP_CALL(UVIO_IOCTL_LOCK_SECRETS_NR)77747875#endif /* __S390_ASM_UVDEVICE_H */
···9696config S390_UV_UAPI9797 def_tristate m9898 prompt "Ultravisor userspace API"9999- depends on S3909999+ depends on S390 && (KVM || PROTECTED_VIRTUALIZATION_GUEST)100100 help101101 Selecting exposes parts of the UV interface to userspace102102 by providing a misc character device at /dev/uv.
+224-7
drivers/s390/char/uvdevice.c
···3232#include <asm/uvdevice.h>3333#include <asm/uv.h>34343535+#define BIT_UVIO_INTERNAL U32_MAX3636+/* Mapping from IOCTL-nr to UVC-bit */3737+static const u32 ioctl_nr_to_uvc_bit[] __initconst = {3838+ [UVIO_IOCTL_UVDEV_INFO_NR] = BIT_UVIO_INTERNAL,3939+ [UVIO_IOCTL_ATT_NR] = BIT_UVC_CMD_RETR_ATTEST,4040+ [UVIO_IOCTL_ADD_SECRET_NR] = BIT_UVC_CMD_ADD_SECRET,4141+ [UVIO_IOCTL_LIST_SECRETS_NR] = BIT_UVC_CMD_LIST_SECRETS,4242+ [UVIO_IOCTL_LOCK_SECRETS_NR] = BIT_UVC_CMD_LOCK_SECRETS,4343+};4444+4545+static_assert(ARRAY_SIZE(ioctl_nr_to_uvc_bit) == UVIO_IOCTL_NUM_IOCTLS);4646+4747+static struct uvio_uvdev_info uvdev_info = {4848+ .supp_uvio_cmds = GENMASK_ULL(UVIO_IOCTL_NUM_IOCTLS - 1, 0),4949+};5050+5151+static void __init set_supp_uv_cmds(unsigned long *supp_uv_cmds)5252+{5353+ int i;5454+5555+ for (i = 0; i < UVIO_IOCTL_NUM_IOCTLS; i++) {5656+ if (ioctl_nr_to_uvc_bit[i] == BIT_UVIO_INTERNAL)5757+ continue;5858+ if (!test_bit_inv(ioctl_nr_to_uvc_bit[i], uv_info.inst_calls_list))5959+ continue;6060+ __set_bit(i, supp_uv_cmds);6161+ }6262+}6363+6464+/**6565+ * uvio_uvdev_info() - get information about the uvdevice6666+ *6767+ * @uv_ioctl: ioctl control block6868+ *6969+ * Lists all IOCTLs that are supported by this uvdevice7070+ */7171+static int uvio_uvdev_info(struct uvio_ioctl_cb *uv_ioctl)7272+{7373+ void __user *user_buf_arg = (void __user *)uv_ioctl->argument_addr;7474+7575+ if (uv_ioctl->argument_len < sizeof(uvdev_info))7676+ return -EINVAL;7777+ if (copy_to_user(user_buf_arg, &uvdev_info, sizeof(uvdev_info)))7878+ return -EFAULT;7979+8080+ uv_ioctl->uv_rc = UVC_RC_EXECUTED;8181+ return 0;8282+}8383+3584static int uvio_build_uvcb_attest(struct uv_cb_attest *uvcb_attest, u8 *arcb,3685 u8 *meas, u8 *add_data, struct uvio_attest *uvio_attest)3786{···234185 return ret;235186}236187237237-static int uvio_copy_and_check_ioctl(struct uvio_ioctl_cb *ioctl, void __user *argp)188188+/** uvio_add_secret() - perform an Add Secret UVC189189+ *190190+ * @uv_ioctl: ioctl control block191191+ *192192+ * uvio_add_secret() performs the Add Secret Ultravisor Call.193193+ *194194+ * The given userspace argument address and size are verified to be195195+ * valid but every other check is made by the Ultravisor196196+ * (UV). Therefore UV errors won't result in a negative return197197+ * value. The request is then copied to kernelspace, the UV-call is198198+ * performed and the results are copied back to userspace.199199+ *200200+ * The argument has to point to an Add Secret Request Control Block201201+ * which is an encrypted and cryptographically verified request that202202+ * inserts a protected guest's secrets into the Ultravisor for later203203+ * use.204204+ *205205+ * If the Add Secret UV facility is not present, UV will return206206+ * invalid command rc. This won't be fenced in the driver and does not207207+ * result in a negative return value.208208+ *209209+ * Context: might sleep210210+ *211211+ * Return: 0 on success or a negative error code on error.212212+ */213213+static int uvio_add_secret(struct uvio_ioctl_cb *uv_ioctl)238214{215215+ void __user *user_buf_arg = (void __user *)uv_ioctl->argument_addr;216216+ struct uv_cb_guest_addr uvcb = {217217+ .header.len = sizeof(uvcb),218218+ .header.cmd = UVC_CMD_ADD_SECRET,219219+ };220220+ void *asrcb = NULL;221221+ int ret;222222+223223+ if (uv_ioctl->argument_len > UVIO_ADD_SECRET_MAX_LEN)224224+ return -EINVAL;225225+ if (uv_ioctl->argument_len == 0)226226+ return -EINVAL;227227+228228+ asrcb = kvzalloc(uv_ioctl->argument_len, GFP_KERNEL);229229+ if (!asrcb)230230+ return -ENOMEM;231231+232232+ ret = -EFAULT;233233+ if (copy_from_user(asrcb, user_buf_arg, uv_ioctl->argument_len))234234+ goto out;235235+236236+ ret = 0;237237+ uvcb.addr = (u64)asrcb;238238+ uv_call_sched(0, (u64)&uvcb);239239+ uv_ioctl->uv_rc = uvcb.header.rc;240240+ uv_ioctl->uv_rrc = uvcb.header.rrc;241241+242242+out:243243+ kvfree(asrcb);244244+ return ret;245245+}246246+247247+/** uvio_list_secrets() - perform a List Secret UVC248248+ * @uv_ioctl: ioctl control block249249+ *250250+ * uvio_list_secrets() performs the List Secret Ultravisor Call. It verifies251251+ * that the given userspace argument address is valid and its size is sane.252252+ * Every other check is made by the Ultravisor (UV) and won't result in a253253+ * negative return value. It builds the request, performs the UV-call, and254254+ * copies the result to userspace.255255+ *256256+ * The argument specifies the location for the result of the UV-Call.257257+ *258258+ * If the List Secrets UV facility is not present, UV will return invalid259259+ * command rc. This won't be fenced in the driver and does not result in a260260+ * negative return value.261261+ *262262+ * Context: might sleep263263+ *264264+ * Return: 0 on success or a negative error code on error.265265+ */266266+static int uvio_list_secrets(struct uvio_ioctl_cb *uv_ioctl)267267+{268268+ void __user *user_buf_arg = (void __user *)uv_ioctl->argument_addr;269269+ struct uv_cb_guest_addr uvcb = {270270+ .header.len = sizeof(uvcb),271271+ .header.cmd = UVC_CMD_LIST_SECRETS,272272+ };273273+ void *secrets = NULL;274274+ int ret = 0;275275+276276+ if (uv_ioctl->argument_len != UVIO_LIST_SECRETS_LEN)277277+ return -EINVAL;278278+279279+ secrets = kvzalloc(UVIO_LIST_SECRETS_LEN, GFP_KERNEL);280280+ if (!secrets)281281+ return -ENOMEM;282282+283283+ uvcb.addr = (u64)secrets;284284+ uv_call_sched(0, (u64)&uvcb);285285+ uv_ioctl->uv_rc = uvcb.header.rc;286286+ uv_ioctl->uv_rrc = uvcb.header.rrc;287287+288288+ if (copy_to_user(user_buf_arg, secrets, UVIO_LIST_SECRETS_LEN))289289+ ret = -EFAULT;290290+291291+ kvfree(secrets);292292+ return ret;293293+}294294+295295+/** uvio_lock_secrets() - perform a Lock Secret Store UVC296296+ * @uv_ioctl: ioctl control block297297+ *298298+ * uvio_lock_secrets() performs the Lock Secret Store Ultravisor Call. It299299+ * performs the UV-call and copies the return codes to the ioctl control block.300300+ * After this call was dispatched successfully every following Add Secret UVC301301+ * and Lock Secrets UVC will fail with return code 0x102.302302+ *303303+ * The argument address and size must be 0.304304+ *305305+ * If the Lock Secrets UV facility is not present, UV will return invalid306306+ * command rc. This won't be fenced in the driver and does not result in a307307+ * negative return value.308308+ *309309+ * Context: might sleep310310+ *311311+ * Return: 0 on success or a negative error code on error.312312+ */313313+static int uvio_lock_secrets(struct uvio_ioctl_cb *ioctl)314314+{315315+ struct uv_cb_nodata uvcb = {316316+ .header.len = sizeof(uvcb),317317+ .header.cmd = UVC_CMD_LOCK_SECRETS,318318+ };319319+320320+ if (ioctl->argument_addr || ioctl->argument_len)321321+ return -EINVAL;322322+323323+ uv_call(0, (u64)&uvcb);324324+ ioctl->uv_rc = uvcb.header.rc;325325+ ioctl->uv_rrc = uvcb.header.rrc;326326+327327+ return 0;328328+}329329+330330+static int uvio_copy_and_check_ioctl(struct uvio_ioctl_cb *ioctl, void __user *argp,331331+ unsigned long cmd)332332+{333333+ u8 nr = _IOC_NR(cmd);334334+335335+ if (_IOC_DIR(cmd) != (_IOC_READ | _IOC_WRITE))336336+ return -ENOIOCTLCMD;337337+ if (_IOC_TYPE(cmd) != UVIO_TYPE_UVC)338338+ return -ENOIOCTLCMD;339339+ if (nr >= UVIO_IOCTL_NUM_IOCTLS)340340+ return -ENOIOCTLCMD;341341+ if (_IOC_SIZE(cmd) != sizeof(*ioctl))342342+ return -ENOIOCTLCMD;239343 if (copy_from_user(ioctl, argp, sizeof(*ioctl)))240344 return -EFAULT;241345 if (ioctl->flags != 0)···396194 if (memchr_inv(ioctl->reserved14, 0, sizeof(ioctl->reserved14)))397195 return -EINVAL;398196399399- return 0;197197+ return nr;400198}401199402200/*···407205 void __user *argp = (void __user *)arg;408206 struct uvio_ioctl_cb uv_ioctl = { };409207 long ret;208208+ int nr;410209411411- switch (cmd) {412412- case UVIO_IOCTL_ATT:413413- ret = uvio_copy_and_check_ioctl(&uv_ioctl, argp);414414- if (ret)415415- return ret;210210+ nr = uvio_copy_and_check_ioctl(&uv_ioctl, argp, cmd);211211+ if (nr < 0)212212+ return nr;213213+214214+ switch (nr) {215215+ case UVIO_IOCTL_UVDEV_INFO_NR:216216+ ret = uvio_uvdev_info(&uv_ioctl);217217+ break;218218+ case UVIO_IOCTL_ATT_NR:416219 ret = uvio_attestation(&uv_ioctl);220220+ break;221221+ case UVIO_IOCTL_ADD_SECRET_NR:222222+ ret = uvio_add_secret(&uv_ioctl);223223+ break;224224+ case UVIO_IOCTL_LIST_SECRETS_NR:225225+ ret = uvio_list_secrets(&uv_ioctl);226226+ break;227227+ case UVIO_IOCTL_LOCK_SECRETS_NR:228228+ ret = uvio_lock_secrets(&uv_ioctl);417229 break;418230 default:419231 ret = -ENOIOCTLCMD;···461245462246static int __init uvio_dev_init(void)463247{248248+ set_supp_uv_cmds((unsigned long *)&uvdev_info.supp_uv_cmds);464249 return misc_register(&uvio_dev_miscdev);465250}466251