s390/cio: Externalize full CMG characteristics

The current "measurement_chars" CHPID sysfs attribute exposes only a
limited, validity-filtered portion of data from the associated Channel-
Measurements Characteristics Block (CMCB). New machine models add data
that is relevant for userspace tooling to the "header"-portion of the
CMCB. This data that is not currently accessible to userspace.

To prevent having to add new sysfs attributes whenever a new bit of data
is added to the CMCB "header", add a new sysfs attribute named
"measurement_chars_full" that exposes the full, unfiltered CMCB.

Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Reviewed-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
This commit is contained in:
Peter Oberparleiter 2024-11-07 15:50:36 +01:00 committed by Heiko Carstens
parent 182c02a6cd
commit 2f4b3b83b8
4 changed files with 39 additions and 20 deletions

View File

@ -144,6 +144,18 @@ static ssize_t measurement_chars_read(struct file *filp, struct kobject *kobj,
}
static BIN_ATTR_ADMIN_RO(measurement_chars, sizeof(struct cmg_chars));
static ssize_t measurement_chars_full_read(struct file *filp,
struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
struct channel_path *chp = to_channelpath(kobj_to_dev(kobj));
return memory_read_from_buffer(buf, count, &off, &chp->cmcb,
sizeof(chp->cmcb));
}
static BIN_ATTR_ADMIN_RO(measurement_chars_full, sizeof(struct cmg_cmcb));
static ssize_t chp_measurement_copy_block(void *buf, loff_t off, size_t count,
struct kobject *kobj, bool extended)
{
@ -201,6 +213,7 @@ static BIN_ATTR_ADMIN_RO(ext_measurement, sizeof(struct cmg_ext_entry));
static struct bin_attribute *measurement_attrs[] = {
&bin_attr_measurement_chars,
&bin_attr_measurement_chars_full,
&bin_attr_measurement,
&bin_attr_ext_measurement,
NULL,

View File

@ -54,6 +54,7 @@ struct channel_path {
int extended;
unsigned long speed;
struct cmg_chars cmg_chars;
struct cmg_cmcb cmcb;
};
/* Return channel_path struct for given chpid. */

View File

@ -1092,19 +1092,7 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp)
u32 zeroes1;
struct chsc_header response;
u32 zeroes2;
u32 not_valid : 1;
u32 shared : 1;
u32 extended : 1;
u32 : 21;
u32 chpid : 8;
u32 cmcv : 5;
u32 : 7;
u32 cmgp : 4;
u32 cmgq : 8;
u32 cmg : 8;
u32 : 16;
u32 cmgs : 16;
u32 data[NR_MEASUREMENT_CHARS];
struct cmg_cmcb cmcb;
} *scmc_area;
chp->shared = -1;
@ -1135,15 +1123,16 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp)
scmc_area->response.code);
goto out;
}
if (scmc_area->not_valid)
chp->cmcb = scmc_area->cmcb;
if (scmc_area->cmcb.not_valid)
goto out;
chp->cmg = scmc_area->cmg;
chp->shared = scmc_area->shared;
chp->extended = scmc_area->extended;
chp->speed = scmc_get_speed(scmc_area->cmgs, scmc_area->cmgp);
chsc_initialize_cmg_chars(chp, scmc_area->cmcv,
(struct cmg_chars *) &scmc_area->data);
chp->cmg = scmc_area->cmcb.cmg;
chp->shared = scmc_area->cmcb.shared;
chp->extended = scmc_area->cmcb.extended;
chp->speed = scmc_get_speed(scmc_area->cmcb.cmgs, scmc_area->cmcb.cmgp);
chsc_initialize_cmg_chars(chp, scmc_area->cmcb.cmcv,
(struct cmg_chars *)&scmc_area->cmcb.data);
out:
spin_unlock_irqrestore(&chsc_page_lock, flags);
return ret;

View File

@ -17,6 +17,22 @@ struct cmg_chars {
u32 values[NR_MEASUREMENT_CHARS];
};
struct cmg_cmcb {
u32 not_valid : 1;
u32 shared : 1;
u32 extended : 1;
u32 : 21;
u32 chpid : 8;
u32 cmcv : 5;
u32 : 7;
u32 cmgp : 4;
u32 cmgq : 8;
u32 cmg : 8;
u32 : 16;
u32 cmgs : 16;
u32 data[NR_MEASUREMENT_CHARS];
};
#define NR_MEASUREMENT_ENTRIES 8
struct cmg_entry {
u32 values[NR_MEASUREMENT_ENTRIES];