Skip to content

Commit b96b3ce

Browse files
steffen-eidenfrankjaa
authored andcommitted
s390/uvdevice: Add 'List Secrets' UVC
Userspace can call the List Secrets Ultravisor Call using IOCTLs on the uvdevice. The List Secrets UV call lists the identifier of the secrets in the UV secret store. The uvdevice is merely transporting the request from userspace to Ultravisor. It's neither checking nor manipulating the request or response data. Signed-off-by: Steffen Eiden <seiden@linux.ibm.com> Reviewed-by: Janosch Frank <frankja@linux.ibm.com> Link: https://lore.kernel.org/r/20230615100533.3996107-5-seiden@linux.ibm.com Signed-off-by: Janosch Frank <frankja@linux.ibm.com> Message-Id: <20230615100533.3996107-5-seiden@linux.ibm.com>
1 parent 44567ca commit b96b3ce

3 files changed

Lines changed: 59 additions & 0 deletions

File tree

arch/s390/include/asm/uv.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
#define UVC_CMD_REMOVE_SHARED_ACCESS 0x1001
6060
#define UVC_CMD_RETR_ATTEST 0x1020
6161
#define UVC_CMD_ADD_SECRET 0x1031
62+
#define UVC_CMD_LIST_SECRETS 0x1033
6263

6364
/* Bits in installed uv calls */
6465
enum uv_cmds_inst {
@@ -90,6 +91,7 @@ enum uv_cmds_inst {
9091
BIT_UVC_CMD_DUMP_COMPLETE = 27,
9192
BIT_UVC_CMD_RETR_ATTEST = 28,
9293
BIT_UVC_CMD_ADD_SECRET = 29,
94+
BIT_UVC_CMD_LIST_SECRETS = 30,
9395
};
9496

9597
enum uv_feat_ind {
@@ -298,6 +300,7 @@ struct uv_cb_dump_complete {
298300
* A common UV call struct for pv guests that contains a single address
299301
* Examples:
300302
* Add Secret
303+
* List Secrets
301304
*/
302305
struct uv_cb_guest_addr {
303306
struct uv_cb_header header;

arch/s390/include/uapi/asm/uvdevice.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ struct uvio_uvdev_info {
7070
#define UVIO_ATT_MEASUREMENT_MAX_LEN 0x8000
7171
#define UVIO_ATT_ADDITIONAL_MAX_LEN 0x8000
7272
#define UVIO_ADD_SECRET_MAX_LEN 0x100000
73+
#define UVIO_LIST_SECRETS_LEN 0x1000
7374

7475
#define UVIO_DEVICE_NAME "uv"
7576
#define UVIO_TYPE_UVC 'u'
@@ -78,6 +79,7 @@ enum UVIO_IOCTL_NR {
7879
UVIO_IOCTL_UVDEV_INFO_NR = 0x00,
7980
UVIO_IOCTL_ATT_NR,
8081
UVIO_IOCTL_ADD_SECRET_NR,
82+
UVIO_IOCTL_LIST_SECRETS_NR,
8183
/* must be the last entry */
8284
UVIO_IOCTL_NUM_IOCTLS
8385
};
@@ -86,10 +88,12 @@ enum UVIO_IOCTL_NR {
8688
#define UVIO_IOCTL_UVDEV_INFO UVIO_IOCTL(UVIO_IOCTL_UVDEV_INFO_NR)
8789
#define UVIO_IOCTL_ATT UVIO_IOCTL(UVIO_IOCTL_ATT_NR)
8890
#define UVIO_IOCTL_ADD_SECRET UVIO_IOCTL(UVIO_IOCTL_ADD_SECRET_NR)
91+
#define UVIO_IOCTL_LIST_SECRETS UVIO_IOCTL(UVIO_IOCTL_LIST_SECRETS_NR)
8992

9093
#define UVIO_SUPP_CALL(nr) (1ULL << (nr))
9194
#define UVIO_SUPP_UDEV_INFO UVIO_SUPP_CALL(UVIO_IOCTL_UDEV_INFO_NR)
9295
#define UVIO_SUPP_ATT UVIO_SUPP_CALL(UVIO_IOCTL_ATT_NR)
9396
#define UVIO_SUPP_ADD_SECRET UVIO_SUPP_CALL(UVIO_IOCTL_ADD_SECRET_NR)
97+
#define UVIO_SUPP_LIST_SECRETS UVIO_SUPP_CALL(UVIO_IOCTL_LIST_SECRETS_NR)
9498

9599
#endif /* __S390_ASM_UVDEVICE_H */

drivers/s390/char/uvdevice.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ 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,
41+
[UVIO_IOCTL_LIST_SECRETS_NR] = BIT_UVC_CMD_LIST_SECRETS,
4142
};
4243

4344
static_assert(ARRAY_SIZE(ioctl_nr_to_uvc_bit) == UVIO_IOCTL_NUM_IOCTLS);
@@ -291,6 +292,54 @@ static int uvio_add_secret(struct uvio_ioctl_cb *uv_ioctl)
291292
return ret;
292293
}
293294

295+
/** uvio_list_secrets() - perform a List Secret UVC
296+
* @uv_ioctl: ioctl control block
297+
*
298+
* uvio_list_secrets() performs the List Secret Ultravisor Call. It verifies
299+
* that the given userspace argument address is valid and its size is sane.
300+
* Every other check is made by the Ultravisor (UV) and won't result in a
301+
* negative return value. It builds the request, performs the UV-call, and
302+
* copies the result to userspace.
303+
*
304+
* The argument specifies the location for the result of the UV-Call.
305+
*
306+
* If the List Secrets UV facility is not present, UV will return invalid
307+
* command rc. This won't be fenced in the driver and does not result in a
308+
* negative return value.
309+
*
310+
* Context: might sleep
311+
*
312+
* Return: 0 on success or a negative error code on error.
313+
*/
314+
static int uvio_list_secrets(struct uvio_ioctl_cb *uv_ioctl)
315+
{
316+
void __user *user_buf_arg = (void __user *)uv_ioctl->argument_addr;
317+
struct uv_cb_guest_addr uvcb = {
318+
.header.len = sizeof(uvcb),
319+
.header.cmd = UVC_CMD_LIST_SECRETS,
320+
};
321+
void *secrets = NULL;
322+
int ret = 0;
323+
324+
if (uv_ioctl->argument_len != UVIO_LIST_SECRETS_LEN)
325+
return -EINVAL;
326+
327+
secrets = kvzalloc(UVIO_LIST_SECRETS_LEN, GFP_KERNEL);
328+
if (!secrets)
329+
return -ENOMEM;
330+
331+
uvcb.addr = (u64)secrets;
332+
uv_call_sched(0, (u64)&uvcb);
333+
uv_ioctl->uv_rc = uvcb.header.rc;
334+
uv_ioctl->uv_rrc = uvcb.header.rrc;
335+
336+
if (copy_to_user(user_buf_arg, secrets, UVIO_LIST_SECRETS_LEN))
337+
ret = -EFAULT;
338+
339+
kvfree(secrets);
340+
return ret;
341+
}
342+
294343
static int uvio_copy_and_check_ioctl(struct uvio_ioctl_cb *ioctl, void __user *argp,
295344
unsigned long cmd)
296345
{
@@ -338,6 +387,9 @@ static long uvio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
338387
case UVIO_IOCTL_ADD_SECRET_NR:
339388
ret = uvio_add_secret(&uv_ioctl);
340389
break;
390+
case UVIO_IOCTL_LIST_SECRETS_NR:
391+
ret = uvio_list_secrets(&uv_ioctl);
392+
break;
341393
default:
342394
ret = -ENOIOCTLCMD;
343395
break;

0 commit comments

Comments
 (0)