Skip to content

Commit a443e26

Browse files
committed
Merge tag 'kvm-s390-next-6.5-1' of https://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux into HEAD
* New uvdevice secret API * New CMM selftest * cmm fix * diag 9c racy access of target cpu fix
2 parents 6995e2d + db54dfc commit a443e26

11 files changed

Lines changed: 1100 additions & 49 deletions

File tree

arch/s390/boot/uv.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ void uv_query_info(void)
4747
uv_info.conf_dump_finalize_len = uvcb.conf_dump_finalize_len;
4848
uv_info.supp_att_req_hdr_ver = uvcb.supp_att_req_hdr_ver;
4949
uv_info.supp_att_pflags = uvcb.supp_att_pflags;
50+
uv_info.supp_add_secret_req_ver = uvcb.supp_add_secret_req_ver;
51+
uv_info.supp_add_secret_pcf = uvcb.supp_add_secret_pcf;
52+
uv_info.supp_secret_types = uvcb.supp_secret_types;
53+
uv_info.max_secrets = uvcb.max_secrets;
5054
}
5155

5256
#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST

arch/s390/include/asm/uv.h

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@
5858
#define UVC_CMD_SET_SHARED_ACCESS 0x1000
5959
#define UVC_CMD_REMOVE_SHARED_ACCESS 0x1001
6060
#define UVC_CMD_RETR_ATTEST 0x1020
61+
#define UVC_CMD_ADD_SECRET 0x1031
62+
#define UVC_CMD_LIST_SECRETS 0x1033
63+
#define UVC_CMD_LOCK_SECRETS 0x1034
6164

6265
/* Bits in installed uv calls */
6366
enum uv_cmds_inst {
@@ -88,6 +91,9 @@ enum uv_cmds_inst {
8891
BIT_UVC_CMD_DUMP_CPU = 26,
8992
BIT_UVC_CMD_DUMP_COMPLETE = 27,
9093
BIT_UVC_CMD_RETR_ATTEST = 28,
94+
BIT_UVC_CMD_ADD_SECRET = 29,
95+
BIT_UVC_CMD_LIST_SECRETS = 30,
96+
BIT_UVC_CMD_LOCK_SECRETS = 31,
9197
};
9298

9399
enum uv_feat_ind {
@@ -117,7 +123,7 @@ struct uv_cb_qui {
117123
u32 reserved70[3]; /* 0x0070 */
118124
u32 max_num_sec_conf; /* 0x007c */
119125
u64 max_guest_stor_addr; /* 0x0080 */
120-
u8 reserved88[158 - 136]; /* 0x0088 */
126+
u8 reserved88[0x9e - 0x88]; /* 0x0088 */
121127
u16 max_guest_cpu_id; /* 0x009e */
122128
u64 uv_feature_indications; /* 0x00a0 */
123129
u64 reserveda8; /* 0x00a8 */
@@ -129,7 +135,12 @@ struct uv_cb_qui {
129135
u64 reservedd8; /* 0x00d8 */
130136
u64 supp_att_req_hdr_ver; /* 0x00e0 */
131137
u64 supp_att_pflags; /* 0x00e8 */
132-
u8 reservedf0[256 - 240]; /* 0x00f0 */
138+
u64 reservedf0; /* 0x00f0 */
139+
u64 supp_add_secret_req_ver; /* 0x00f8 */
140+
u64 supp_add_secret_pcf; /* 0x0100 */
141+
u64 supp_secret_types; /* 0x0180 */
142+
u16 max_secrets; /* 0x0110 */
143+
u8 reserved112[0x120 - 0x112]; /* 0x0112 */
133144
} __packed __aligned(8);
134145

135146
/* Initialize Ultravisor */
@@ -292,6 +303,19 @@ struct uv_cb_dump_complete {
292303
u64 reserved30[5];
293304
} __packed __aligned(8);
294305

306+
/*
307+
* A common UV call struct for pv guests that contains a single address
308+
* Examples:
309+
* Add Secret
310+
* List Secrets
311+
*/
312+
struct uv_cb_guest_addr {
313+
struct uv_cb_header header;
314+
u64 reserved08[3];
315+
u64 addr;
316+
u64 reserved28[4];
317+
} __packed __aligned(8);
318+
295319
static inline int __uv_call(unsigned long r1, unsigned long r2)
296320
{
297321
int cc;
@@ -365,6 +389,10 @@ struct uv_info {
365389
unsigned long conf_dump_finalize_len;
366390
unsigned long supp_att_req_hdr_ver;
367391
unsigned long supp_att_pflags;
392+
unsigned long supp_add_secret_req_ver;
393+
unsigned long supp_add_secret_pcf;
394+
unsigned long supp_secret_types;
395+
unsigned short max_secrets;
368396
};
369397

370398
extern struct uv_info uv_info;

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

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,33 @@ struct uvio_attest {
3232
__u16 reserved136; /* 0x0136 */
3333
};
3434

35+
/**
36+
* uvio_uvdev_info - Information of supported functions
37+
* @supp_uvio_cmds - supported IOCTLs by this device
38+
* @supp_uv_cmds - supported UVCs corresponding to the IOCTL
39+
*
40+
* UVIO request to get information about supported request types by this
41+
* uvdevice and the Ultravisor. Everything is output. Bits are in LSB0
42+
* ordering. If the bit is set in both, @supp_uvio_cmds and @supp_uv_cmds, the
43+
* uvdevice and the Ultravisor support that call.
44+
*
45+
* Note that bit 0 (UVIO_IOCTL_UVDEV_INFO_NR) is always zero for `supp_uv_cmds`
46+
* as there is no corresponding UV-call.
47+
*/
48+
struct uvio_uvdev_info {
49+
/*
50+
* If bit `n` is set, this device supports the IOCTL with nr `n`.
51+
*/
52+
__u64 supp_uvio_cmds;
53+
/*
54+
* If bit `n` is set, the Ultravisor(UV) supports the UV-call
55+
* corresponding to the IOCTL with nr `n` in the calling contextx (host
56+
* or guest). The value is only valid if the corresponding bit in
57+
* @supp_uvio_cmds is set as well.
58+
*/
59+
__u64 supp_uv_cmds;
60+
};
61+
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
@@ -42,10 +69,34 @@ struct uvio_attest {
4269
#define UVIO_ATT_ARCB_MAX_LEN 0x100000
4370
#define UVIO_ATT_MEASUREMENT_MAX_LEN 0x8000
4471
#define UVIO_ATT_ADDITIONAL_MAX_LEN 0x8000
72+
#define UVIO_ADD_SECRET_MAX_LEN 0x100000
73+
#define UVIO_LIST_SECRETS_LEN 0x1000
4574

4675
#define UVIO_DEVICE_NAME "uv"
4776
#define UVIO_TYPE_UVC 'u'
4877

49-
#define UVIO_IOCTL_ATT _IOWR(UVIO_TYPE_UVC, 0x01, struct uvio_ioctl_cb)
78+
enum UVIO_IOCTL_NR {
79+
UVIO_IOCTL_UVDEV_INFO_NR = 0x00,
80+
UVIO_IOCTL_ATT_NR,
81+
UVIO_IOCTL_ADD_SECRET_NR,
82+
UVIO_IOCTL_LIST_SECRETS_NR,
83+
UVIO_IOCTL_LOCK_SECRETS_NR,
84+
/* must be the last entry */
85+
UVIO_IOCTL_NUM_IOCTLS
86+
};
87+
88+
#define UVIO_IOCTL(nr) _IOWR(UVIO_TYPE_UVC, nr, struct uvio_ioctl_cb)
89+
#define UVIO_IOCTL_UVDEV_INFO UVIO_IOCTL(UVIO_IOCTL_UVDEV_INFO_NR)
90+
#define UVIO_IOCTL_ATT UVIO_IOCTL(UVIO_IOCTL_ATT_NR)
91+
#define UVIO_IOCTL_ADD_SECRET UVIO_IOCTL(UVIO_IOCTL_ADD_SECRET_NR)
92+
#define UVIO_IOCTL_LIST_SECRETS UVIO_IOCTL(UVIO_IOCTL_LIST_SECRETS_NR)
93+
#define UVIO_IOCTL_LOCK_SECRETS UVIO_IOCTL(UVIO_IOCTL_LOCK_SECRETS_NR)
94+
95+
#define UVIO_SUPP_CALL(nr) (1ULL << (nr))
96+
#define UVIO_SUPP_UDEV_INFO UVIO_SUPP_CALL(UVIO_IOCTL_UDEV_INFO_NR)
97+
#define UVIO_SUPP_ATT UVIO_SUPP_CALL(UVIO_IOCTL_ATT_NR)
98+
#define UVIO_SUPP_ADD_SECRET UVIO_SUPP_CALL(UVIO_IOCTL_ADD_SECRET_NR)
99+
#define UVIO_SUPP_LIST_SECRETS UVIO_SUPP_CALL(UVIO_IOCTL_LIST_SECRETS_NR)
100+
#define UVIO_SUPP_LOCK_SECRETS UVIO_SUPP_CALL(UVIO_IOCTL_LOCK_SECRETS_NR)
50101

51102
#endif /* __S390_ASM_UVDEVICE_H */

arch/s390/kernel/uv.c

Lines changed: 75 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,20 @@
2323
int __bootdata_preserved(prot_virt_guest);
2424
#endif
2525

26+
/*
27+
* uv_info contains both host and guest information but it's currently only
28+
* expected to be used within modules if it's the KVM module or for
29+
* any PV guest module.
30+
*
31+
* The kernel itself will write these values once in uv_query_info()
32+
* and then make some of them readable via a sysfs interface.
33+
*/
2634
struct uv_info __bootdata_preserved(uv_info);
35+
EXPORT_SYMBOL(uv_info);
2736

2837
#if IS_ENABLED(CONFIG_KVM)
2938
int __bootdata_preserved(prot_virt_host);
3039
EXPORT_SYMBOL(prot_virt_host);
31-
EXPORT_SYMBOL(uv_info);
3240

3341
static int __init uv_init(phys_addr_t stor_base, unsigned long stor_len)
3442
{
@@ -460,13 +468,13 @@ EXPORT_SYMBOL_GPL(arch_make_page_accessible);
460468

461469
#if defined(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) || IS_ENABLED(CONFIG_KVM)
462470
static ssize_t uv_query_facilities(struct kobject *kobj,
463-
struct kobj_attribute *attr, char *page)
471+
struct kobj_attribute *attr, char *buf)
464472
{
465-
return scnprintf(page, PAGE_SIZE, "%lx\n%lx\n%lx\n%lx\n",
466-
uv_info.inst_calls_list[0],
467-
uv_info.inst_calls_list[1],
468-
uv_info.inst_calls_list[2],
469-
uv_info.inst_calls_list[3]);
473+
return sysfs_emit(buf, "%lx\n%lx\n%lx\n%lx\n",
474+
uv_info.inst_calls_list[0],
475+
uv_info.inst_calls_list[1],
476+
uv_info.inst_calls_list[2],
477+
uv_info.inst_calls_list[3]);
470478
}
471479

472480
static struct kobj_attribute uv_query_facilities_attr =
@@ -491,30 +499,27 @@ static struct kobj_attribute uv_query_supp_se_hdr_pcf_attr =
491499
__ATTR(supp_se_hdr_pcf, 0444, uv_query_supp_se_hdr_pcf, NULL);
492500

493501
static ssize_t uv_query_dump_cpu_len(struct kobject *kobj,
494-
struct kobj_attribute *attr, char *page)
502+
struct kobj_attribute *attr, char *buf)
495503
{
496-
return scnprintf(page, PAGE_SIZE, "%lx\n",
497-
uv_info.guest_cpu_stor_len);
504+
return sysfs_emit(buf, "%lx\n", uv_info.guest_cpu_stor_len);
498505
}
499506

500507
static struct kobj_attribute uv_query_dump_cpu_len_attr =
501508
__ATTR(uv_query_dump_cpu_len, 0444, uv_query_dump_cpu_len, NULL);
502509

503510
static ssize_t uv_query_dump_storage_state_len(struct kobject *kobj,
504-
struct kobj_attribute *attr, char *page)
511+
struct kobj_attribute *attr, char *buf)
505512
{
506-
return scnprintf(page, PAGE_SIZE, "%lx\n",
507-
uv_info.conf_dump_storage_state_len);
513+
return sysfs_emit(buf, "%lx\n", uv_info.conf_dump_storage_state_len);
508514
}
509515

510516
static struct kobj_attribute uv_query_dump_storage_state_len_attr =
511517
__ATTR(dump_storage_state_len, 0444, uv_query_dump_storage_state_len, NULL);
512518

513519
static ssize_t uv_query_dump_finalize_len(struct kobject *kobj,
514-
struct kobj_attribute *attr, char *page)
520+
struct kobj_attribute *attr, char *buf)
515521
{
516-
return scnprintf(page, PAGE_SIZE, "%lx\n",
517-
uv_info.conf_dump_finalize_len);
522+
return sysfs_emit(buf, "%lx\n", uv_info.conf_dump_finalize_len);
518523
}
519524

520525
static struct kobj_attribute uv_query_dump_finalize_len_attr =
@@ -530,53 +535,86 @@ static struct kobj_attribute uv_query_feature_indications_attr =
530535
__ATTR(feature_indications, 0444, uv_query_feature_indications, NULL);
531536

532537
static ssize_t uv_query_max_guest_cpus(struct kobject *kobj,
533-
struct kobj_attribute *attr, char *page)
538+
struct kobj_attribute *attr, char *buf)
534539
{
535-
return scnprintf(page, PAGE_SIZE, "%d\n",
536-
uv_info.max_guest_cpu_id + 1);
540+
return sysfs_emit(buf, "%d\n", uv_info.max_guest_cpu_id + 1);
537541
}
538542

539543
static struct kobj_attribute uv_query_max_guest_cpus_attr =
540544
__ATTR(max_cpus, 0444, uv_query_max_guest_cpus, NULL);
541545

542546
static ssize_t uv_query_max_guest_vms(struct kobject *kobj,
543-
struct kobj_attribute *attr, char *page)
547+
struct kobj_attribute *attr, char *buf)
544548
{
545-
return scnprintf(page, PAGE_SIZE, "%d\n",
546-
uv_info.max_num_sec_conf);
549+
return sysfs_emit(buf, "%d\n", uv_info.max_num_sec_conf);
547550
}
548551

549552
static struct kobj_attribute uv_query_max_guest_vms_attr =
550553
__ATTR(max_guests, 0444, uv_query_max_guest_vms, NULL);
551554

552555
static ssize_t uv_query_max_guest_addr(struct kobject *kobj,
553-
struct kobj_attribute *attr, char *page)
556+
struct kobj_attribute *attr, char *buf)
554557
{
555-
return scnprintf(page, PAGE_SIZE, "%lx\n",
556-
uv_info.max_sec_stor_addr);
558+
return sysfs_emit(buf, "%lx\n", uv_info.max_sec_stor_addr);
557559
}
558560

559561
static struct kobj_attribute uv_query_max_guest_addr_attr =
560562
__ATTR(max_address, 0444, uv_query_max_guest_addr, NULL);
561563

562564
static ssize_t uv_query_supp_att_req_hdr_ver(struct kobject *kobj,
563-
struct kobj_attribute *attr, char *page)
565+
struct kobj_attribute *attr, char *buf)
564566
{
565-
return scnprintf(page, PAGE_SIZE, "%lx\n", uv_info.supp_att_req_hdr_ver);
567+
return sysfs_emit(buf, "%lx\n", uv_info.supp_att_req_hdr_ver);
566568
}
567569

568570
static struct kobj_attribute uv_query_supp_att_req_hdr_ver_attr =
569571
__ATTR(supp_att_req_hdr_ver, 0444, uv_query_supp_att_req_hdr_ver, NULL);
570572

571573
static ssize_t uv_query_supp_att_pflags(struct kobject *kobj,
572-
struct kobj_attribute *attr, char *page)
574+
struct kobj_attribute *attr, char *buf)
573575
{
574-
return scnprintf(page, PAGE_SIZE, "%lx\n", uv_info.supp_att_pflags);
576+
return sysfs_emit(buf, "%lx\n", uv_info.supp_att_pflags);
575577
}
576578

577579
static struct kobj_attribute uv_query_supp_att_pflags_attr =
578580
__ATTR(supp_att_pflags, 0444, uv_query_supp_att_pflags, NULL);
579581

582+
static ssize_t uv_query_supp_add_secret_req_ver(struct kobject *kobj,
583+
struct kobj_attribute *attr, char *buf)
584+
{
585+
return sysfs_emit(buf, "%lx\n", uv_info.supp_add_secret_req_ver);
586+
}
587+
588+
static struct kobj_attribute uv_query_supp_add_secret_req_ver_attr =
589+
__ATTR(supp_add_secret_req_ver, 0444, uv_query_supp_add_secret_req_ver, NULL);
590+
591+
static ssize_t uv_query_supp_add_secret_pcf(struct kobject *kobj,
592+
struct kobj_attribute *attr, char *buf)
593+
{
594+
return sysfs_emit(buf, "%lx\n", uv_info.supp_add_secret_pcf);
595+
}
596+
597+
static struct kobj_attribute uv_query_supp_add_secret_pcf_attr =
598+
__ATTR(supp_add_secret_pcf, 0444, uv_query_supp_add_secret_pcf, NULL);
599+
600+
static ssize_t uv_query_supp_secret_types(struct kobject *kobj,
601+
struct kobj_attribute *attr, char *buf)
602+
{
603+
return sysfs_emit(buf, "%lx\n", uv_info.supp_secret_types);
604+
}
605+
606+
static struct kobj_attribute uv_query_supp_secret_types_attr =
607+
__ATTR(supp_secret_types, 0444, uv_query_supp_secret_types, NULL);
608+
609+
static ssize_t uv_query_max_secrets(struct kobject *kobj,
610+
struct kobj_attribute *attr, char *buf)
611+
{
612+
return sysfs_emit(buf, "%d\n", uv_info.max_secrets);
613+
}
614+
615+
static struct kobj_attribute uv_query_max_secrets_attr =
616+
__ATTR(max_secrets, 0444, uv_query_max_secrets, NULL);
617+
580618
static struct attribute *uv_query_attrs[] = {
581619
&uv_query_facilities_attr.attr,
582620
&uv_query_feature_indications_attr.attr,
@@ -590,6 +628,10 @@ static struct attribute *uv_query_attrs[] = {
590628
&uv_query_dump_cpu_len_attr.attr,
591629
&uv_query_supp_att_req_hdr_ver_attr.attr,
592630
&uv_query_supp_att_pflags_attr.attr,
631+
&uv_query_supp_add_secret_req_ver_attr.attr,
632+
&uv_query_supp_add_secret_pcf_attr.attr,
633+
&uv_query_supp_secret_types_attr.attr,
634+
&uv_query_max_secrets_attr.attr,
593635
NULL,
594636
};
595637

@@ -598,26 +640,26 @@ static struct attribute_group uv_query_attr_group = {
598640
};
599641

600642
static ssize_t uv_is_prot_virt_guest(struct kobject *kobj,
601-
struct kobj_attribute *attr, char *page)
643+
struct kobj_attribute *attr, char *buf)
602644
{
603645
int val = 0;
604646

605647
#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
606648
val = prot_virt_guest;
607649
#endif
608-
return scnprintf(page, PAGE_SIZE, "%d\n", val);
650+
return sysfs_emit(buf, "%d\n", val);
609651
}
610652

611653
static ssize_t uv_is_prot_virt_host(struct kobject *kobj,
612-
struct kobj_attribute *attr, char *page)
654+
struct kobj_attribute *attr, char *buf)
613655
{
614656
int val = 0;
615657

616658
#if IS_ENABLED(CONFIG_KVM)
617659
val = prot_virt_host;
618660
#endif
619661

620-
return scnprintf(page, PAGE_SIZE, "%d\n", val);
662+
return sysfs_emit(buf, "%d\n", val);
621663
}
622664

623665
static struct kobj_attribute uv_prot_virt_guest =

0 commit comments

Comments
 (0)