[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <772ea26a-7133-8401-3e0d-0fef17b75638@linux.ibm.com>
Date: Wed, 16 Mar 2022 09:56:48 +0100
From: Janosch Frank <frankja@...ux.ibm.com>
To: Steffen Eiden <seiden@...ux.ibm.com>, linux-s390@...r.kernel.org
Cc: Heiko Carstens <hca@...ux.ibm.com>,
Vasily Gorbik <gor@...ux.ibm.com>,
Christian Borntraeger <borntraeger@...ux.ibm.com>,
Alexander Gordeev <agordeev@...ux.ibm.com>,
David Hildenbrand <david@...hat.com>,
Claudio Imbrenda <imbrenda@...ux.ibm.com>,
Shuah Khan <shuah@...nel.org>, Nico Boehr <nrb@...ux.ibm.com>,
linux-kernel@...r.kernel.org, kvm@...r.kernel.org,
linux-kselftest@...r.kernel.org
Subject: Re: [PATCH v3 2/4] drivers/s390/char: Add Query Ultravisor
Information to uvdevice
On 3/4/22 15:11, Steffen Eiden wrote:
> This patch enables userspace to call the Query Ultravisor Information
> Ultravisor Call using IOCTLs on the uvdevice.
>
> The uvdevice will do some sanity checks first, build the UVCB,
> perform the UV call, and copy the result to userspace.
>
> Signed-off-by: Steffen Eiden <seiden@...ux.ibm.com>
Reviewed-by: Janosch Frank <frankja@...ux.ibm.com>
> ---
> arch/s390/include/uapi/asm/uvdevice.h | 2 +
> drivers/s390/char/uvdevice.c | 56 +++++++++++++++++++++++++++
> 2 files changed, 58 insertions(+)
>
> diff --git a/arch/s390/include/uapi/asm/uvdevice.h b/arch/s390/include/uapi/asm/uvdevice.h
> index d40f69345c75..7520bdde3102 100644
> --- a/arch/s390/include/uapi/asm/uvdevice.h
> +++ b/arch/s390/include/uapi/asm/uvdevice.h
> @@ -42,10 +42,12 @@ struct uvio_attest {
> #define UVIO_ATT_ARCB_MAX_LEN 0x100000
> #define UVIO_ATT_MEASUREMENT_MAX_LEN 0x8000
> #define UVIO_ATT_ADDITIONAL_MAX_LEN 0x8000
> +#define UVIO_QUI_MAX_LEN 0x8000
>
> #define UVIO_DEVICE_NAME "uv"
> #define UVIO_TYPE_UVC 'u'
>
> #define UVIO_IOCTL_ATT _IOWR(UVIO_TYPE_UVC, 0x01, struct uvio_ioctl_cb)
> +#define UVIO_IOCTL_QUI _IOWR(UVIO_TYPE_UVC, 0x02, struct uvio_ioctl_cb)
>
> #endif /* __S390X_ASM_UVDEVICE_H */
> diff --git a/drivers/s390/char/uvdevice.c b/drivers/s390/char/uvdevice.c
> index b720dc8d0bd9..cfce8c5999e6 100644
> --- a/drivers/s390/char/uvdevice.c
> +++ b/drivers/s390/char/uvdevice.c
> @@ -31,6 +31,55 @@
> #include <asm/uvdevice.h>
> #include <asm/uv.h>
>
> +/**
> + * uvio_qui() - Perform a Query Ultravisor Information UVC.
> + *
> + * uv_ioctl: ioctl control block
> + *
> + * uvio_qui() does a Query Ultravisor Information (QUI) Ultravisor Call.
> + * It creates the uvc qui request and sends it to the Ultravisor. After that
> + * it copies the response to userspace and fills the rc and rrc of uv_ioctl
> + * uv_call with the response values of the Ultravisor.
> + *
> + * Create the UVC structure, send the UVC to UV and write the response in the ioctl struct.
> + *
> + * Return: 0 on success or a negative error code on error.
> + */
> +static int uvio_qui(struct uvio_ioctl_cb *uv_ioctl)
> +{
> + u8 __user *user_buf_addr = (__user u8 *)uv_ioctl->argument_addr;
> + size_t user_buf_len = uv_ioctl->argument_len;
> + struct uv_cb_header *uvcb_qui = NULL;
> + int ret;
> +
> + /*
> + * Do not check for a too small buffer. If userspace provides a buffer
> + * that is too small the Ultravisor will complain.
> + */
> + ret = -EINVAL;
> + if (!user_buf_len || user_buf_len > UVIO_QUI_MAX_LEN)
> + goto out;
> + ret = -ENOMEM;
> + uvcb_qui = kvzalloc(user_buf_len, GFP_KERNEL);
> + if (!uvcb_qui)
> + goto out;
> + uvcb_qui->len = user_buf_len;
> + uvcb_qui->cmd = UVC_CMD_QUI;
> +
> + uv_call(0, (u64)uvcb_qui);
> +
> + ret = -EFAULT;
> + if (copy_to_user(user_buf_addr, uvcb_qui, uvcb_qui->len))
> + goto out;
> + uv_ioctl->uv_rc = uvcb_qui->rc;
> + uv_ioctl->uv_rrc = uvcb_qui->rrc;
> +
> + ret = 0;
> +out:
> + kvfree(uvcb_qui);
> + return ret;
> +}
> +
> static int uvio_build_uvcb_attest(struct uv_cb_attest *uvcb_attest, u8 *arcb,
> u8 *meas, u8 *add_data, struct uvio_attest *uvio_attest)
> {
> @@ -217,6 +266,13 @@ static long uvio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
> goto out;
> ret = uvio_attestation(uv_ioctl);
> break;
> + case UVIO_IOCTL_QUI:
> + ret = uvio_copy_and_check_ioctl(uv_ioctl, argp);
> + if (ret)
> + goto out;
> + ret = uvio_qui(uv_ioctl);
> + break;
> +
> default:
> ret = -ENOIOCTLCMD;
> break;
Powered by blists - more mailing lists