Commit 4689752c authored by Steffen Eiden's avatar Steffen Eiden Committed by Janosch Frank
Browse files

drivers/s390/char: Add Ultravisor io device



This patch adds a new miscdevice to expose some Ultravisor functions
to userspace. Userspace can send IOCTLs to the uvdevice that will then
emit a corresponding Ultravisor Call and hands the result over to
userspace. The uvdevice is available if the Ultravisor Call facility is
present.
Userspace can call the Retrieve Attestation Measurement
Ultravisor Call using IOCTLs on the uvdevice.

The uvdevice will do some sanity checks first.
Then, copy the request data to kernel space, build the UVCB,
perform the UV call, and copy the result back to userspace.

Signed-off-by: default avatarSteffen Eiden <seiden@linux.ibm.com>
Reviewed-by: default avatarJanosch Frank <frankja@linux.ibm.com>
Reviewed-by: default avatarClaudio Imbrenda <imbrenda@linux.ibm.com>
Link: https://lore.kernel.org/kvm/20220516113335.338212-1-seiden@linux.ibm.com/
Message-Id: <20220516113335.338212-1-seiden@linux.ibm.com>
Signed-off-by: Janosch Frank <frankja@linux.ibm.com> (whitespace and  tristate fixes, pick)
parent ce522ba9
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -10779,9 +10779,11 @@ F: Documentation/virt/kvm/s390*
F:	arch/s390/include/asm/gmap.h
F:	arch/s390/include/asm/kvm*
F:	arch/s390/include/uapi/asm/kvm*
F:	arch/s390/include/uapi/asm/uvdevice.h
F:	arch/s390/kernel/uv.c
F:	arch/s390/kvm/
F:	arch/s390/mm/gmap.c
F:	drivers/s390/char/uvdevice.c
F:	tools/testing/selftests/kvm/*/s390x/
F:	tools/testing/selftests/kvm/s390x/
+22 −1
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
/*
 * Ultravisor Interfaces
 *
 * Copyright IBM Corp. 2019
 * Copyright IBM Corp. 2019, 2022
 *
 * Author(s):
 *	Vasily Gorbik <gor@linux.ibm.com>
@@ -52,6 +52,7 @@
#define UVC_CMD_UNPIN_PAGE_SHARED	0x0342
#define UVC_CMD_SET_SHARED_ACCESS	0x1000
#define UVC_CMD_REMOVE_SHARED_ACCESS	0x1001
#define UVC_CMD_RETR_ATTEST		0x1020

/* Bits in installed uv calls */
enum uv_cmds_inst {
@@ -76,6 +77,7 @@ enum uv_cmds_inst {
	BIT_UVC_CMD_UNSHARE_ALL = 20,
	BIT_UVC_CMD_PIN_PAGE_SHARED = 21,
	BIT_UVC_CMD_UNPIN_PAGE_SHARED = 22,
	BIT_UVC_CMD_RETR_ATTEST = 28,
};

enum uv_feat_ind {
@@ -219,6 +221,25 @@ struct uv_cb_share {
	u64 reserved28;
} __packed __aligned(8);

/* Retrieve Attestation Measurement */
struct uv_cb_attest {
	struct uv_cb_header header;	/* 0x0000 */
	u64 reserved08[2];		/* 0x0008 */
	u64 arcb_addr;			/* 0x0018 */
	u64 cont_token;			/* 0x0020 */
	u8  reserved28[6];		/* 0x0028 */
	u16 user_data_len;		/* 0x002e */
	u8  user_data[256];		/* 0x0030 */
	u32 reserved130[3];		/* 0x0130 */
	u32 meas_len;			/* 0x013c */
	u64 meas_addr;			/* 0x0140 */
	u8  config_uid[16];		/* 0x0148 */
	u32 reserved158;		/* 0x0158 */
	u32 add_data_len;		/* 0x015c */
	u64 add_data_addr;		/* 0x0160 */
	u64 reserved168[4];		/* 0x0168 */
} __packed __aligned(8);

static inline int __uv_call(unsigned long r1, unsigned long r2)
{
	int cc;
+51 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
 *  Copyright IBM Corp. 2022
 *  Author(s): Steffen Eiden <seiden@linux.ibm.com>
 */
#ifndef __S390_ASM_UVDEVICE_H
#define __S390_ASM_UVDEVICE_H

#include <linux/types.h>

struct uvio_ioctl_cb {
	__u32 flags;
	__u16 uv_rc;			/* UV header rc value */
	__u16 uv_rrc;			/* UV header rrc value */
	__u64 argument_addr;		/* Userspace address of uvio argument */
	__u32 argument_len;
	__u8  reserved14[0x40 - 0x14];	/* must be zero */
};

#define UVIO_ATT_USER_DATA_LEN		0x100
#define UVIO_ATT_UID_LEN		0x10
struct uvio_attest {
	__u64 arcb_addr;				/* 0x0000 */
	__u64 meas_addr;				/* 0x0008 */
	__u64 add_data_addr;				/* 0x0010 */
	__u8  user_data[UVIO_ATT_USER_DATA_LEN];	/* 0x0018 */
	__u8  config_uid[UVIO_ATT_UID_LEN];		/* 0x0118 */
	__u32 arcb_len;					/* 0x0128 */
	__u32 meas_len;					/* 0x012c */
	__u32 add_data_len;				/* 0x0130 */
	__u16 user_data_len;				/* 0x0134 */
	__u16 reserved136;				/* 0x0136 */
};

/*
 * The following max values define an upper length for the IOCTL in/out buffers.
 * However, they do not represent the maximum the Ultravisor allows which is
 * often way smaller. By allowing larger buffer sizes we hopefully do not need
 * to update the code with every machine update. It is therefore possible for
 * userspace to request more memory than actually used by kernel/UV.
 */
#define UVIO_ATT_ARCB_MAX_LEN		0x100000
#define UVIO_ATT_MEASUREMENT_MAX_LEN	0x8000
#define UVIO_ATT_ADDITIONAL_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)

#endif /* __S390_ASM_UVDEVICE_H */
+10 −0
Original line number Diff line number Diff line
@@ -100,6 +100,16 @@ config SCLP_OFB
	  This option enables the Open-for-Business interface to the s390
	  Service Element.

config S390_UV_UAPI
	def_tristate m
	prompt "Ultravisor userspace API"
	help
	  Selecting exposes parts of the UV interface to userspace
	  by providing a misc character device at /dev/uv.
	  Using IOCTLs one can interact with the UV.
	  The device is only available if the Ultravisor
	  Facility (158) is present.

config S390_TAPE
	def_tristate m
	prompt "S/390 tape device support"
+1 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ obj-$(CONFIG_MONREADER) += monreader.o
obj-$(CONFIG_MONWRITER) += monwriter.o
obj-$(CONFIG_S390_VMUR) += vmur.o
obj-$(CONFIG_CRASH_DUMP) += sclp_sdias.o zcore.o
obj-$(CONFIG_S390_UV_UAPI) += uvdevice.o

hmcdrv-objs := hmcdrv_mod.o hmcdrv_dev.o hmcdrv_ftp.o hmcdrv_cache.o diag_ftp.o sclp_ftp.o
obj-$(CONFIG_HMC_DRV) += hmcdrv.o
Loading