Blame view
arch/s390/hypfs/hypfs_vm.c
6.62 KB
31cb4bd31 [S390] Hypervisor... |
1 2 3 |
/* * Hypervisor filesystem for Linux on s390. z/VM implementation. * |
a53c8fab3 s390/comments: un... |
4 |
* Copyright IBM Corp. 2006 |
31cb4bd31 [S390] Hypervisor... |
5 6 7 8 9 10 11 12 |
* Author(s): Michael Holzheu <holzheu@de.ibm.com> */ #include <linux/types.h> #include <linux/errno.h> #include <linux/string.h> #include <linux/vmalloc.h> #include <asm/ebcdic.h> |
57b28f663 [S390] s390_hypfs... |
13 |
#include <asm/timex.h> |
31cb4bd31 [S390] Hypervisor... |
14 15 16 |
#include "hypfs.h" #define NAME_LEN 8 |
57b28f663 [S390] s390_hypfs... |
17 |
#define DBFS_D2FC_HDR_VERSION 0 |
31cb4bd31 [S390] Hypervisor... |
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
static char local_guest[] = " "; static char all_guests[] = "* "; static char *guest_query; struct diag2fc_data { __u32 version; __u32 flags; __u64 used_cpu; __u64 el_time; __u64 mem_min_kb; __u64 mem_max_kb; __u64 mem_share_kb; __u64 mem_used_kb; __u32 pcpus; __u32 lcpus; __u32 vcpus; |
36a554021 hypfs: Add clarif... |
35 |
__u32 ocpus; |
31cb4bd31 [S390] Hypervisor... |
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
__u32 cpu_max; __u32 cpu_shares; __u32 cpu_use_samp; __u32 cpu_delay_samp; __u32 page_wait_samp; __u32 idle_samp; __u32 other_samp; __u32 total_samp; char guest_name[NAME_LEN]; }; struct diag2fc_parm_list { char userid[NAME_LEN]; char aci_grp[NAME_LEN]; __u64 addr; __u32 size; __u32 fmt; }; static int diag2fc(int size, char* query, void *addr) { unsigned long residual_cnt; unsigned long rc; struct diag2fc_parm_list parm_list; memcpy(parm_list.userid, query, NAME_LEN); ASCEBC(parm_list.userid, NAME_LEN); parm_list.addr = (unsigned long) addr ; parm_list.size = size; parm_list.fmt = 0x02; memset(parm_list.aci_grp, 0x40, NAME_LEN); rc = -1; asm volatile( " diag %0,%1,0x2fc " "0: " EX_TABLE(0b,0b) : "=d" (residual_cnt), "+d" (rc) : "0" (&parm_list) : "memory"); if ((rc != 0 ) && (rc != -2)) return rc; else return -residual_cnt; } |
57b28f663 [S390] s390_hypfs... |
82 83 84 85 |
/* * Allocate buffer for "query" and store diag 2fc at "offset" */ static void *diag2fc_store(char *query, unsigned int *count, int offset) |
31cb4bd31 [S390] Hypervisor... |
86 |
{ |
57b28f663 [S390] s390_hypfs... |
87 |
void *data; |
31cb4bd31 [S390] Hypervisor... |
88 |
int size; |
31cb4bd31 [S390] Hypervisor... |
89 90 91 92 93 |
do { size = diag2fc(0, query, NULL); if (size < 0) return ERR_PTR(-EACCES); |
57b28f663 [S390] s390_hypfs... |
94 |
data = vmalloc(size + offset); |
31cb4bd31 [S390] Hypervisor... |
95 96 |
if (!data) return ERR_PTR(-ENOMEM); |
57b28f663 [S390] s390_hypfs... |
97 |
if (diag2fc(size, query, data + offset) == 0) |
31cb4bd31 [S390] Hypervisor... |
98 99 100 |
break; vfree(data); } while (1); |
57b28f663 [S390] s390_hypfs... |
101 |
*count = (size / sizeof(struct diag2fc_data)); |
31cb4bd31 [S390] Hypervisor... |
102 103 104 |
return data; } |
2fcb3686e [S390] hypfs: Mov... |
105 |
static void diag2fc_free(const void *data) |
31cb4bd31 [S390] Hypervisor... |
106 107 108 |
{ vfree(data); } |
f78e41e3f don't pass superb... |
109 |
#define ATTRIBUTE(dir, name, member) \ |
31cb4bd31 [S390] Hypervisor... |
110 111 |
do { \ void *rc; \ |
a118cfdf9 don't pass superb... |
112 |
rc = hypfs_create_u64(dir, name, member); \ |
31cb4bd31 [S390] Hypervisor... |
113 114 115 |
if (IS_ERR(rc)) \ return PTR_ERR(rc); \ } while(0) |
f78e41e3f don't pass superb... |
116 |
static int hpyfs_vm_create_guest(struct dentry *systems_dir, |
31cb4bd31 [S390] Hypervisor... |
117 118 119 120 121 122 123 124 125 126 127 128 |
struct diag2fc_data *data) { char guest_name[NAME_LEN + 1] = {}; struct dentry *guest_dir, *cpus_dir, *samples_dir, *mem_dir; int dedicated_flag, capped_value; capped_value = (data->flags & 0x00000006) >> 1; dedicated_flag = (data->flags & 0x00000008) >> 3; /* guest dir */ memcpy(guest_name, data->guest_name, NAME_LEN); EBCASC(guest_name, NAME_LEN); |
1d802e247 [S390] Use strim ... |
129 |
strim(guest_name); |
a118cfdf9 don't pass superb... |
130 |
guest_dir = hypfs_mkdir(systems_dir, guest_name); |
31cb4bd31 [S390] Hypervisor... |
131 132 |
if (IS_ERR(guest_dir)) return PTR_ERR(guest_dir); |
f78e41e3f don't pass superb... |
133 |
ATTRIBUTE(guest_dir, "onlinetime_us", data->el_time); |
31cb4bd31 [S390] Hypervisor... |
134 135 |
/* logical cpu information */ |
a118cfdf9 don't pass superb... |
136 |
cpus_dir = hypfs_mkdir(guest_dir, "cpus"); |
31cb4bd31 [S390] Hypervisor... |
137 138 |
if (IS_ERR(cpus_dir)) return PTR_ERR(cpus_dir); |
f78e41e3f don't pass superb... |
139 140 141 142 |
ATTRIBUTE(cpus_dir, "cputime_us", data->used_cpu); ATTRIBUTE(cpus_dir, "capped", capped_value); ATTRIBUTE(cpus_dir, "dedicated", dedicated_flag); ATTRIBUTE(cpus_dir, "count", data->vcpus); |
36a554021 hypfs: Add clarif... |
143 144 145 146 147 148 |
/* * Note: The "weight_min" attribute got the wrong name. * The value represents the number of non-stopped (operating) * CPUS. */ ATTRIBUTE(cpus_dir, "weight_min", data->ocpus); |
f78e41e3f don't pass superb... |
149 150 |
ATTRIBUTE(cpus_dir, "weight_max", data->cpu_max); ATTRIBUTE(cpus_dir, "weight_cur", data->cpu_shares); |
31cb4bd31 [S390] Hypervisor... |
151 152 |
/* memory information */ |
a118cfdf9 don't pass superb... |
153 |
mem_dir = hypfs_mkdir(guest_dir, "mem"); |
31cb4bd31 [S390] Hypervisor... |
154 155 |
if (IS_ERR(mem_dir)) return PTR_ERR(mem_dir); |
f78e41e3f don't pass superb... |
156 157 158 159 |
ATTRIBUTE(mem_dir, "min_KiB", data->mem_min_kb); ATTRIBUTE(mem_dir, "max_KiB", data->mem_max_kb); ATTRIBUTE(mem_dir, "used_KiB", data->mem_used_kb); ATTRIBUTE(mem_dir, "share_KiB", data->mem_share_kb); |
31cb4bd31 [S390] Hypervisor... |
160 161 |
/* samples */ |
a118cfdf9 don't pass superb... |
162 |
samples_dir = hypfs_mkdir(guest_dir, "samples"); |
31cb4bd31 [S390] Hypervisor... |
163 164 |
if (IS_ERR(samples_dir)) return PTR_ERR(samples_dir); |
f78e41e3f don't pass superb... |
165 166 167 168 169 170 |
ATTRIBUTE(samples_dir, "cpu_using", data->cpu_use_samp); ATTRIBUTE(samples_dir, "cpu_delay", data->cpu_delay_samp); ATTRIBUTE(samples_dir, "mem_delay", data->page_wait_samp); ATTRIBUTE(samples_dir, "idle", data->idle_samp); ATTRIBUTE(samples_dir, "other", data->other_samp); ATTRIBUTE(samples_dir, "total", data->total_samp); |
31cb4bd31 [S390] Hypervisor... |
171 172 |
return 0; } |
f78e41e3f don't pass superb... |
173 |
int hypfs_vm_create_files(struct dentry *root) |
31cb4bd31 [S390] Hypervisor... |
174 175 176 |
{ struct dentry *dir, *file; struct diag2fc_data *data; |
57b28f663 [S390] s390_hypfs... |
177 178 |
unsigned int count = 0; int rc, i; |
31cb4bd31 [S390] Hypervisor... |
179 |
|
57b28f663 [S390] s390_hypfs... |
180 |
data = diag2fc_store(guest_query, &count, 0); |
31cb4bd31 [S390] Hypervisor... |
181 182 183 184 |
if (IS_ERR(data)) return PTR_ERR(data); /* Hpervisor Info */ |
a118cfdf9 don't pass superb... |
185 |
dir = hypfs_mkdir(root, "hyp"); |
31cb4bd31 [S390] Hypervisor... |
186 187 188 189 |
if (IS_ERR(dir)) { rc = PTR_ERR(dir); goto failed; } |
a118cfdf9 don't pass superb... |
190 |
file = hypfs_create_str(dir, "type", "z/VM Hypervisor"); |
31cb4bd31 [S390] Hypervisor... |
191 192 193 194 195 196 |
if (IS_ERR(file)) { rc = PTR_ERR(file); goto failed; } /* physical cpus */ |
a118cfdf9 don't pass superb... |
197 |
dir = hypfs_mkdir(root, "cpus"); |
31cb4bd31 [S390] Hypervisor... |
198 199 200 201 |
if (IS_ERR(dir)) { rc = PTR_ERR(dir); goto failed; } |
a118cfdf9 don't pass superb... |
202 |
file = hypfs_create_u64(dir, "count", data->lcpus); |
31cb4bd31 [S390] Hypervisor... |
203 204 205 206 207 208 |
if (IS_ERR(file)) { rc = PTR_ERR(file); goto failed; } /* guests */ |
a118cfdf9 don't pass superb... |
209 |
dir = hypfs_mkdir(root, "systems"); |
31cb4bd31 [S390] Hypervisor... |
210 211 212 213 214 215 |
if (IS_ERR(dir)) { rc = PTR_ERR(dir); goto failed; } for (i = 0; i < count; i++) { |
f78e41e3f don't pass superb... |
216 |
rc = hpyfs_vm_create_guest(dir, &(data[i])); |
31cb4bd31 [S390] Hypervisor... |
217 218 219 220 221 222 223 224 225 226 |
if (rc) goto failed; } diag2fc_free(data); return 0; failed: diag2fc_free(data); return rc; } |
57b28f663 [S390] s390_hypfs... |
227 228 229 230 231 232 233 234 235 236 237 238 |
struct dbfs_d2fc_hdr { u64 len; /* Length of d2fc buffer without header */ u16 version; /* Version of header */ char tod_ext[16]; /* TOD clock for d2fc */ u64 count; /* Number of VM guests in d2fc buffer */ char reserved[30]; } __attribute__ ((packed)); struct dbfs_d2fc { struct dbfs_d2fc_hdr hdr; /* 64 byte header */ char buf[]; /* d2fc buffer */ } __attribute__ ((packed)); |
2fcb3686e [S390] hypfs: Mov... |
239 |
static int dbfs_diag2fc_create(void **data, void **data_free_ptr, size_t *size) |
57b28f663 [S390] s390_hypfs... |
240 |
{ |
2fcb3686e [S390] hypfs: Mov... |
241 |
struct dbfs_d2fc *d2fc; |
57b28f663 [S390] s390_hypfs... |
242 |
unsigned int count; |
2fcb3686e [S390] hypfs: Mov... |
243 244 245 |
d2fc = diag2fc_store(guest_query, &count, sizeof(d2fc->hdr)); if (IS_ERR(d2fc)) return PTR_ERR(d2fc); |
1aae0560d s390/time: rename... |
246 |
get_tod_clock_ext(d2fc->hdr.tod_ext); |
2fcb3686e [S390] hypfs: Mov... |
247 248 249 250 251 252 253 |
d2fc->hdr.len = count * sizeof(struct diag2fc_data); d2fc->hdr.version = DBFS_D2FC_HDR_VERSION; d2fc->hdr.count = count; memset(&d2fc->hdr.reserved, 0, sizeof(d2fc->hdr.reserved)); *data = d2fc; *data_free_ptr = d2fc; *size = d2fc->hdr.len + sizeof(struct dbfs_d2fc_hdr); |
57b28f663 [S390] s390_hypfs... |
254 255 |
return 0; } |
2fcb3686e [S390] hypfs: Mov... |
256 257 258 259 |
static struct hypfs_dbfs_file dbfs_file_2fc = { .name = "diag_2fc", .data_create = dbfs_diag2fc_create, .data_free = diag2fc_free, |
57b28f663 [S390] s390_hypfs... |
260 |
}; |
31cb4bd31 [S390] Hypervisor... |
261 262 |
int hypfs_vm_init(void) { |
57b28f663 [S390] s390_hypfs... |
263 264 |
if (!MACHINE_IS_VM) return 0; |
31cb4bd31 [S390] Hypervisor... |
265 266 267 268 269 270 |
if (diag2fc(0, all_guests, NULL) > 0) guest_query = all_guests; else if (diag2fc(0, local_guest, NULL) > 0) guest_query = local_guest; else return -EACCES; |
2fcb3686e [S390] hypfs: Mov... |
271 |
return hypfs_dbfs_create_file(&dbfs_file_2fc); |
31cb4bd31 [S390] Hypervisor... |
272 |
} |
57b28f663 [S390] s390_hypfs... |
273 274 275 276 277 |
void hypfs_vm_exit(void) { if (!MACHINE_IS_VM) return; |
2fcb3686e [S390] hypfs: Mov... |
278 |
hypfs_dbfs_remove_file(&dbfs_file_2fc); |
57b28f663 [S390] s390_hypfs... |
279 |
} |