2 * Hypervisor filesystem for Linux on s390. z/VM implementation.
4 * Copyright (C) IBM Corp. 2006
5 * Author(s): Michael Holzheu <holzheu@de.ibm.com>
8 #include <linux/types.h>
9 #include <linux/errno.h>
10 #include <linux/string.h>
11 #include <linux/vmalloc.h>
12 #include <asm/ebcdic.h>
17 static char local_guest
[] = " ";
18 static char all_guests
[] = "* ";
19 static char *guest_query
;
42 char guest_name
[NAME_LEN
];
45 struct diag2fc_parm_list
{
46 char userid
[NAME_LEN
];
47 char aci_grp
[NAME_LEN
];
53 static int diag2fc(int size
, char* query
, void *addr
)
55 unsigned long residual_cnt
;
57 struct diag2fc_parm_list parm_list
;
59 memcpy(parm_list
.userid
, query
, NAME_LEN
);
60 ASCEBC(parm_list
.userid
, NAME_LEN
);
61 parm_list
.addr
= (unsigned long) addr
;
62 parm_list
.size
= size
;
64 memset(parm_list
.aci_grp
, 0x40, NAME_LEN
);
71 : "=d" (residual_cnt
), "+d" (rc
) : "0" (&parm_list
) : "memory");
73 if ((rc
!= 0 ) && (rc
!= -2))
79 static struct diag2fc_data
*diag2fc_store(char *query
, int *count
)
82 struct diag2fc_data
*data
;
85 size
= diag2fc(0, query
, NULL
);
87 return ERR_PTR(-EACCES
);
90 return ERR_PTR(-ENOMEM
);
91 if (diag2fc(size
, query
, data
) == 0)
95 *count
= (size
/ sizeof(*data
));
100 static void diag2fc_free(void *data
)
105 #define ATTRIBUTE(sb, dir, name, member) \
108 rc = hypfs_create_u64(sb, dir, name, member); \
110 return PTR_ERR(rc); \
113 static int hpyfs_vm_create_guest(struct super_block
*sb
,
114 struct dentry
*systems_dir
,
115 struct diag2fc_data
*data
)
117 char guest_name
[NAME_LEN
+ 1] = {};
118 struct dentry
*guest_dir
, *cpus_dir
, *samples_dir
, *mem_dir
;
119 int dedicated_flag
, capped_value
;
121 capped_value
= (data
->flags
& 0x00000006) >> 1;
122 dedicated_flag
= (data
->flags
& 0x00000008) >> 3;
125 memcpy(guest_name
, data
->guest_name
, NAME_LEN
);
126 EBCASC(guest_name
, NAME_LEN
);
127 strstrip(guest_name
);
128 guest_dir
= hypfs_mkdir(sb
, systems_dir
, guest_name
);
129 if (IS_ERR(guest_dir
))
130 return PTR_ERR(guest_dir
);
131 ATTRIBUTE(sb
, guest_dir
, "onlinetime_us", data
->el_time
);
133 /* logical cpu information */
134 cpus_dir
= hypfs_mkdir(sb
, guest_dir
, "cpus");
135 if (IS_ERR(cpus_dir
))
136 return PTR_ERR(cpus_dir
);
137 ATTRIBUTE(sb
, cpus_dir
, "cputime_us", data
->used_cpu
);
138 ATTRIBUTE(sb
, cpus_dir
, "capped", capped_value
);
139 ATTRIBUTE(sb
, cpus_dir
, "dedicated", dedicated_flag
);
140 ATTRIBUTE(sb
, cpus_dir
, "count", data
->vcpus
);
141 ATTRIBUTE(sb
, cpus_dir
, "weight_min", data
->cpu_min
);
142 ATTRIBUTE(sb
, cpus_dir
, "weight_max", data
->cpu_max
);
143 ATTRIBUTE(sb
, cpus_dir
, "weight_cur", data
->cpu_shares
);
145 /* memory information */
146 mem_dir
= hypfs_mkdir(sb
, guest_dir
, "mem");
148 return PTR_ERR(mem_dir
);
149 ATTRIBUTE(sb
, mem_dir
, "min_KiB", data
->mem_min_kb
);
150 ATTRIBUTE(sb
, mem_dir
, "max_KiB", data
->mem_max_kb
);
151 ATTRIBUTE(sb
, mem_dir
, "used_KiB", data
->mem_used_kb
);
152 ATTRIBUTE(sb
, mem_dir
, "share_KiB", data
->mem_share_kb
);
155 samples_dir
= hypfs_mkdir(sb
, guest_dir
, "samples");
156 if (IS_ERR(samples_dir
))
157 return PTR_ERR(samples_dir
);
158 ATTRIBUTE(sb
, samples_dir
, "cpu_using", data
->cpu_use_samp
);
159 ATTRIBUTE(sb
, samples_dir
, "cpu_delay", data
->cpu_delay_samp
);
160 ATTRIBUTE(sb
, samples_dir
, "mem_delay", data
->page_wait_samp
);
161 ATTRIBUTE(sb
, samples_dir
, "idle", data
->idle_samp
);
162 ATTRIBUTE(sb
, samples_dir
, "other", data
->other_samp
);
163 ATTRIBUTE(sb
, samples_dir
, "total", data
->total_samp
);
167 int hypfs_vm_create_files(struct super_block
*sb
, struct dentry
*root
)
169 struct dentry
*dir
, *file
;
170 struct diag2fc_data
*data
;
171 int rc
, i
, count
= 0;
173 data
= diag2fc_store(guest_query
, &count
);
175 return PTR_ERR(data
);
178 dir
= hypfs_mkdir(sb
, root
, "hyp");
183 file
= hypfs_create_str(sb
, dir
, "type", "z/VM Hypervisor");
190 dir
= hypfs_mkdir(sb
, root
, "cpus");
195 file
= hypfs_create_u64(sb
, dir
, "count", data
->lcpus
);
202 dir
= hypfs_mkdir(sb
, root
, "systems");
208 for (i
= 0; i
< count
; i
++) {
209 rc
= hpyfs_vm_create_guest(sb
, dir
, &(data
[i
]));
221 int hypfs_vm_init(void)
223 if (diag2fc(0, all_guests
, NULL
) > 0)
224 guest_query
= all_guests
;
225 else if (diag2fc(0, local_guest
, NULL
) > 0)
226 guest_query
= local_guest
;