Skip to content

Commit 3979a03

Browse files
author
Mete Durlu
committed
s390/cio: export extended channel-path-measurement data
JIRA: https://issues.redhat.com/browse/RHEL-50790 commit 2dc8903 Author: Peter Oberparleiter <oberpar@linux.ibm.com> Date: Tue Mar 26 17:03:22 2024 +0100 s390/cio: export extended channel-path-measurement data Add a per-CHPID binary sysfs attribute named "ext_measurement" that provides access to extended channel-path-measurement data for the associated channel path. Note that while not all channel-paths provide extended measurement data this attribute is created unconditionally for all channel paths because channel-path measurement capabilities might change during run-time. Reading from the attribute will only return data for channel-paths that support extended measurement data. Example: $ echo 1 > /sys/devices/css0/cm_enable $ xxd /sys/devices/css0/chp0.32/ext_measurement 00000000: 53e0 8002 0000 0095 0000 0000 59cc e034 S...........Y..4 00000010: 38b8 cc45 0000 0000 0000 0000 3e24 fe94 8..E........>$.. 00000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................ Reviewed-by: Vineeth Vijayan <vneethv@linux.ibm.com> Tested-by: Vineeth Vijayan <vneethv@linux.ibm.com> Acked-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com> Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com> Signed-off-by: Mete Durlu <mdurlu@redhat.com>
1 parent 20b4f0f commit 3979a03

File tree

5 files changed

+69
-32
lines changed

5 files changed

+69
-32
lines changed

drivers/s390/cio/chp.c

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -144,55 +144,65 @@ static ssize_t measurement_chars_read(struct file *filp, struct kobject *kobj,
144144
}
145145
static BIN_ATTR_ADMIN_RO(measurement_chars, sizeof(struct cmg_chars));
146146

147-
static void chp_measurement_copy_block(struct cmg_entry *buf,
148-
struct channel_subsystem *css,
149-
struct chp_id chpid)
150-
{
151-
void *area;
152-
struct cmg_entry *entry, reference_buf;
153-
int idx;
154-
155-
if (chpid.id < CSS_CUES_PER_PAGE) {
156-
area = css->cub[0];
157-
idx = chpid.id;
158-
} else {
159-
area = css->cub[1];
160-
idx = chpid.id - CSS_CUES_PER_PAGE;
161-
}
162-
entry = area + (idx * sizeof(struct cmg_entry));
163-
do {
164-
memcpy(buf, entry, sizeof(*entry));
165-
memcpy(&reference_buf, entry, sizeof(*entry));
166-
} while (reference_buf.values[0] != buf->values[0]);
167-
}
168-
169-
static ssize_t measurement_read(struct file *filp, struct kobject *kobj,
170-
struct bin_attribute *bin_attr,
171-
char *buf, loff_t off, size_t count)
147+
static ssize_t chp_measurement_copy_block(void *buf, loff_t off, size_t count,
148+
struct kobject *kobj, bool extended)
172149
{
173150
struct channel_path *chp;
174151
struct channel_subsystem *css;
175152
struct device *device;
176153
unsigned int size;
154+
void *area, *entry;
155+
int id, idx;
177156

178157
device = kobj_to_dev(kobj);
179158
chp = to_channelpath(device);
180159
css = to_css(chp->dev.parent);
160+
id = chp->chpid.id;
181161

182-
size = sizeof(struct cmg_entry);
162+
if (extended) {
163+
/* Check if extended measurement data is available. */
164+
if (!chp->extended)
165+
return 0;
166+
167+
size = sizeof(struct cmg_ext_entry);
168+
area = css->ecub[id / CSS_ECUES_PER_PAGE];
169+
idx = id % CSS_ECUES_PER_PAGE;
170+
} else {
171+
size = sizeof(struct cmg_entry);
172+
area = css->cub[id / CSS_CUES_PER_PAGE];
173+
idx = id % CSS_CUES_PER_PAGE;
174+
}
175+
entry = area + (idx * size);
183176

184177
/* Only allow single reads. */
185178
if (off || count < size)
186179
return 0;
187-
chp_measurement_copy_block((struct cmg_entry *)buf, css, chp->chpid);
188-
count = size;
189-
return count;
180+
181+
memcpy(buf, entry, size);
182+
183+
return size;
184+
}
185+
186+
static ssize_t measurement_read(struct file *filp, struct kobject *kobj,
187+
struct bin_attribute *bin_attr,
188+
char *buf, loff_t off, size_t count)
189+
{
190+
return chp_measurement_copy_block(buf, off, count, kobj, false);
190191
}
191192
static BIN_ATTR_ADMIN_RO(measurement, sizeof(struct cmg_entry));
192193

194+
static ssize_t ext_measurement_read(struct file *filp, struct kobject *kobj,
195+
struct bin_attribute *bin_attr,
196+
char *buf, loff_t off, size_t count)
197+
{
198+
return chp_measurement_copy_block(buf, off, count, kobj, true);
199+
}
200+
static BIN_ATTR_ADMIN_RO(ext_measurement, sizeof(struct cmg_ext_entry));
201+
193202
static struct bin_attribute *measurement_attrs[] = {
194203
&bin_attr_measurement_chars,
195204
&bin_attr_measurement,
205+
&bin_attr_ext_measurement,
196206
NULL,
197207
};
198208
BIN_ATTRIBUTE_GROUPS(measurement);

drivers/s390/cio/chp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ struct channel_path {
5151
/* Channel-measurement related stuff: */
5252
int cmg;
5353
int shared;
54+
int extended;
5455
struct cmg_chars cmg_chars;
5556
};
5657

drivers/s390/cio/chsc.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -857,11 +857,14 @@ int __chsc_do_secm(struct channel_subsystem *css, int enable)
857857
struct {
858858
struct chsc_header request;
859859
u32 operation_code : 2;
860-
u32 : 30;
860+
u32 : 1;
861+
u32 e : 1;
862+
u32 : 28;
861863
u32 key : 4;
862864
u32 : 28;
863865
dma64_t cub[CSS_NUM_CUB_PAGES];
864-
u32 reserved[13];
866+
dma64_t ecub[CSS_NUM_ECUB_PAGES];
867+
u32 reserved[5];
865868
struct chsc_header response;
866869
u32 status : 8;
867870
u32 : 4;
@@ -878,9 +881,12 @@ int __chsc_do_secm(struct channel_subsystem *css, int enable)
878881
secm_area->request.code = 0x0016;
879882

880883
secm_area->key = PAGE_DEFAULT_KEY >> 4;
884+
secm_area->e = 1;
881885

882886
for (i = 0; i < CSS_NUM_CUB_PAGES; i++)
883887
secm_area->cub[i] = (__force dma64_t)virt_to_dma32(css->cub[i]);
888+
for (i = 0; i < CSS_NUM_ECUB_PAGES; i++)
889+
secm_area->ecub[i] = virt_to_dma64(css->ecub[i]);
884890

885891
secm_area->operation_code = enable ? 0 : 1;
886892

@@ -915,6 +921,11 @@ static int cub_alloc(struct channel_subsystem *css)
915921
if (!css->cub[i])
916922
return -ENOMEM;
917923
}
924+
for (i = 0; i < CSS_NUM_ECUB_PAGES; i++) {
925+
css->ecub[i] = (void *)get_zeroed_page(GFP_KERNEL);
926+
if (!css->ecub[i])
927+
return -ENOMEM;
928+
}
918929

919930
return 0;
920931
}
@@ -927,6 +938,10 @@ static void cub_free(struct channel_subsystem *css)
927938
free_page((unsigned long)css->cub[i]);
928939
css->cub[i] = NULL;
929940
}
941+
for (i = 0; i < CSS_NUM_ECUB_PAGES; i++) {
942+
free_page((unsigned long)css->ecub[i]);
943+
css->ecub[i] = NULL;
944+
}
930945
}
931946

932947
int
@@ -1053,7 +1068,8 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp)
10531068
u32 zeroes2;
10541069
u32 not_valid : 1;
10551070
u32 shared : 1;
1056-
u32 : 22;
1071+
u32 extended : 1;
1072+
u32 : 21;
10571073
u32 chpid : 8;
10581074
u32 cmcv : 5;
10591075
u32 : 11;
@@ -1065,6 +1081,7 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp)
10651081

10661082
chp->shared = -1;
10671083
chp->cmg = -1;
1084+
chp->extended = 0;
10681085

10691086
if (!css_chsc_characteristics.scmc || !css_chsc_characteristics.secm)
10701087
return -EINVAL;
@@ -1094,6 +1111,7 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp)
10941111

10951112
chp->cmg = scmc_area->cmg;
10961113
chp->shared = scmc_area->shared;
1114+
chp->extended = scmc_area->extended;
10971115
if (chp->cmg != 2 && chp->cmg != 3) {
10981116
/* No cmg-dependent data. */
10991117
goto out;

drivers/s390/cio/chsc.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ struct cmg_entry {
2222
u32 values[NR_MEASUREMENT_ENTRIES];
2323
};
2424

25+
#define NR_EXT_MEASUREMENT_ENTRIES 16
26+
struct cmg_ext_entry {
27+
u32 values[NR_EXT_MEASUREMENT_ENTRIES];
28+
};
29+
2530
struct channel_path_desc_fmt1 {
2631
u8 flags;
2732
u8 lsn;

drivers/s390/cio/css.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040

4141
#define CSS_NUM_CUB_PAGES 2
4242
#define CSS_CUES_PER_PAGE 128
43+
#define CSS_NUM_ECUB_PAGES 4
44+
#define CSS_ECUES_PER_PAGE 64
4345

4446
/*
4547
* Conditions used to specify which subchannels need evaluation
@@ -130,6 +132,7 @@ struct channel_subsystem {
130132
/* channel measurement related */
131133
int cm_enabled;
132134
void *cub[CSS_NUM_CUB_PAGES];
135+
void *ecub[CSS_NUM_ECUB_PAGES];
133136
/* for orphaned ccw devices */
134137
struct subchannel *pseudo_subchannel;
135138
};

0 commit comments

Comments
 (0)