Commit 495a5b45 authored by Cornelia Huck's avatar Cornelia Huck Committed by Linus Torvalds

[PATCH] s390: channel path measurements

Gather extended measurements for channel paths from the channel subsystem and
expose them to userspace via a sysfs attribute.
Signed-off-by: default avatarCornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent dc06010c
This diff is collapsed.
...@@ -12,6 +12,16 @@ struct chsc_header { ...@@ -12,6 +12,16 @@ struct chsc_header {
u16 code; u16 code;
}; };
#define NR_MEASUREMENT_CHARS 5
struct cmg_chars {
u32 values[NR_MEASUREMENT_CHARS];
};
#define NR_MEASUREMENT_ENTRIES 8
struct cmg_entry {
u32 values[NR_MEASUREMENT_ENTRIES];
};
struct channel_path_desc { struct channel_path_desc {
u8 flags; u8 flags;
u8 lsn; u8 lsn;
...@@ -27,6 +37,10 @@ struct channel_path { ...@@ -27,6 +37,10 @@ struct channel_path {
int id; int id;
int state; int state;
struct channel_path_desc desc; struct channel_path_desc desc;
/* Channel-measurement related stuff: */
int cmg;
int shared;
void *cmg_chars;
struct device dev; struct device dev;
}; };
...@@ -52,7 +66,11 @@ struct css_general_char { ...@@ -52,7 +66,11 @@ struct css_general_char {
struct css_chsc_char { struct css_chsc_char {
u64 res; u64 res;
u64 : 43; u64 : 20;
u32 secm : 1; /* bit 84 */
u32 : 1;
u32 scmc : 1; /* bit 86 */
u32 : 20;
u32 scssc : 1; /* bit 107 */ u32 scssc : 1; /* bit 107 */
u32 scsscf : 1; /* bit 108 */ u32 scsscf : 1; /* bit 108 */
u32 : 19; u32 : 19;
...@@ -67,6 +85,8 @@ extern int css_characteristics_avail; ...@@ -67,6 +85,8 @@ extern int css_characteristics_avail;
extern void *chsc_get_chp_desc(struct subchannel*, int); extern void *chsc_get_chp_desc(struct subchannel*, int);
extern int chsc_enable_facility(int); extern int chsc_enable_facility(int);
struct channel_subsystem;
extern int chsc_secm(struct channel_subsystem *, int);
#define to_channelpath(device) container_of(device, struct channel_path, dev) #define to_channelpath(device) container_of(device, struct channel_path, dev)
......
...@@ -452,15 +452,50 @@ channel_subsystem_release(struct device *dev) ...@@ -452,15 +452,50 @@ channel_subsystem_release(struct device *dev)
struct channel_subsystem *css; struct channel_subsystem *css;
css = to_css(dev); css = to_css(dev);
mutex_destroy(&css->mutex);
kfree(css); kfree(css);
} }
static ssize_t
css_cm_enable_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct channel_subsystem *css = to_css(dev);
if (!css)
return 0;
return sprintf(buf, "%x\n", css->cm_enabled);
}
static ssize_t
css_cm_enable_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct channel_subsystem *css = to_css(dev);
int ret;
switch (buf[0]) {
case '0':
ret = css->cm_enabled ? chsc_secm(css, 0) : 0;
break;
case '1':
ret = css->cm_enabled ? 0 : chsc_secm(css, 1);
break;
default:
ret = -EINVAL;
}
return ret < 0 ? ret : count;
}
static DEVICE_ATTR(cm_enable, 0644, css_cm_enable_show, css_cm_enable_store);
static inline void __init static inline void __init
setup_css(int nr) setup_css(int nr)
{ {
u32 tod_high; u32 tod_high;
memset(css[nr], 0, sizeof(struct channel_subsystem)); memset(css[nr], 0, sizeof(struct channel_subsystem));
mutex_init(&css[nr]->mutex);
css[nr]->valid = 1; css[nr]->valid = 1;
css[nr]->cssid = nr; css[nr]->cssid = nr;
sprintf(css[nr]->device.bus_id, "css%x", nr); sprintf(css[nr]->device.bus_id, "css%x", nr);
...@@ -507,6 +542,9 @@ init_channel_subsystem (void) ...@@ -507,6 +542,9 @@ init_channel_subsystem (void)
ret = device_register(&css[i]->device); ret = device_register(&css[i]->device);
if (ret) if (ret)
goto out_free; goto out_free;
if (css_characteristics_avail && css_chsc_characteristics.secm)
device_create_file(&css[i]->device,
&dev_attr_cm_enable);
} }
css_init_done = 1; css_init_done = 1;
...@@ -519,6 +557,9 @@ out_free: ...@@ -519,6 +557,9 @@ out_free:
out_unregister: out_unregister:
while (i > 0) { while (i > 0) {
i--; i--;
if (css_characteristics_avail && css_chsc_characteristics.secm)
device_remove_file(&css[i]->device,
&dev_attr_cm_enable);
device_unregister(&css[i]->device); device_unregister(&css[i]->device);
} }
out_bus: out_bus:
......
#ifndef _CSS_H #ifndef _CSS_H
#define _CSS_H #define _CSS_H
#include <linux/mutex.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
...@@ -150,6 +151,11 @@ struct channel_subsystem { ...@@ -150,6 +151,11 @@ struct channel_subsystem {
struct channel_path *chps[__MAX_CHPID + 1]; struct channel_path *chps[__MAX_CHPID + 1];
struct device device; struct device device;
struct pgid global_pgid; struct pgid global_pgid;
struct mutex mutex;
/* channel measurement related */
int cm_enabled;
void *cub_addr1;
void *cub_addr2;
}; };
#define to_css(dev) container_of(dev, struct channel_subsystem, device) #define to_css(dev) container_of(dev, struct channel_subsystem, device)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment