OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [arch/] [s390/] [hypfs/] [hypfs_vm.c] - Blame information for rev 63

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 63 marcus.erl
/*
2
 *    Hypervisor filesystem for Linux on s390. z/VM implementation.
3
 *
4
 *    Copyright (C) IBM Corp. 2006
5
 *    Author(s): Michael Holzheu <holzheu@de.ibm.com>
6
 */
7
 
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>
13
#include "hypfs.h"
14
 
15
#define NAME_LEN 8
16
 
17
static char local_guest[] = "        ";
18
static char all_guests[] = "*       ";
19
static char *guest_query;
20
 
21
struct diag2fc_data {
22
        __u32 version;
23
        __u32 flags;
24
        __u64 used_cpu;
25
        __u64 el_time;
26
        __u64 mem_min_kb;
27
        __u64 mem_max_kb;
28
        __u64 mem_share_kb;
29
        __u64 mem_used_kb;
30
        __u32 pcpus;
31
        __u32 lcpus;
32
        __u32 vcpus;
33
        __u32 cpu_min;
34
        __u32 cpu_max;
35
        __u32 cpu_shares;
36
        __u32 cpu_use_samp;
37
        __u32 cpu_delay_samp;
38
        __u32 page_wait_samp;
39
        __u32 idle_samp;
40
        __u32 other_samp;
41
        __u32 total_samp;
42
        char  guest_name[NAME_LEN];
43
};
44
 
45
struct diag2fc_parm_list {
46
        char userid[NAME_LEN];
47
        char aci_grp[NAME_LEN];
48
        __u64 addr;
49
        __u32 size;
50
        __u32 fmt;
51
};
52
 
53
static int diag2fc(int size, char* query, void *addr)
54
{
55
        unsigned long residual_cnt;
56
        unsigned long rc;
57
        struct diag2fc_parm_list parm_list;
58
 
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;
63
        parm_list.fmt = 0x02;
64
        memset(parm_list.aci_grp, 0x40, NAME_LEN);
65
        rc = -1;
66
 
67
        asm volatile(
68
                "       diag    %0,%1,0x2fc\n"
69
                "0:\n"
70
                EX_TABLE(0b,0b)
71
                : "=d" (residual_cnt), "+d" (rc) : "0" (&parm_list) : "memory");
72
 
73
        if ((rc != 0 ) && (rc != -2))
74
                return rc;
75
        else
76
                return -residual_cnt;
77
}
78
 
79
static struct diag2fc_data *diag2fc_store(char *query, int *count)
80
{
81
        int size;
82
        struct diag2fc_data *data;
83
 
84
        do {
85
                size = diag2fc(0, query, NULL);
86
                if (size < 0)
87
                        return ERR_PTR(-EACCES);
88
                data = vmalloc(size);
89
                if (!data)
90
                        return ERR_PTR(-ENOMEM);
91
                if (diag2fc(size, query, data) == 0)
92
                        break;
93
                vfree(data);
94
        } while (1);
95
        *count = (size / sizeof(*data));
96
 
97
        return data;
98
}
99
 
100
static void diag2fc_free(void *data)
101
{
102
        vfree(data);
103
}
104
 
105
#define ATTRIBUTE(sb, dir, name, member) \
106
do { \
107
        void *rc; \
108
        rc = hypfs_create_u64(sb, dir, name, member); \
109
        if (IS_ERR(rc)) \
110
                return PTR_ERR(rc); \
111
} while(0)
112
 
113
static int hpyfs_vm_create_guest(struct super_block *sb,
114
                                 struct dentry *systems_dir,
115
                                 struct diag2fc_data *data)
116
{
117
        char guest_name[NAME_LEN + 1] = {};
118
        struct dentry *guest_dir, *cpus_dir, *samples_dir, *mem_dir;
119
        int dedicated_flag, capped_value;
120
 
121
        capped_value = (data->flags & 0x00000006) >> 1;
122
        dedicated_flag = (data->flags & 0x00000008) >> 3;
123
 
124
        /* guest dir */
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);
132
 
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);
144
 
145
        /* memory information */
146
        mem_dir = hypfs_mkdir(sb, guest_dir, "mem");
147
        if (IS_ERR(mem_dir))
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);
153
 
154
        /* samples */
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);
164
        return 0;
165
}
166
 
167
int hypfs_vm_create_files(struct super_block *sb, struct dentry *root)
168
{
169
        struct dentry *dir, *file;
170
        struct diag2fc_data *data;
171
        int rc, i, count = 0;
172
 
173
        data = diag2fc_store(guest_query, &count);
174
        if (IS_ERR(data))
175
                return PTR_ERR(data);
176
 
177
        /* Hpervisor Info */
178
        dir = hypfs_mkdir(sb, root, "hyp");
179
        if (IS_ERR(dir)) {
180
                rc = PTR_ERR(dir);
181
                goto failed;
182
        }
183
        file = hypfs_create_str(sb, dir, "type", "z/VM Hypervisor");
184
        if (IS_ERR(file)) {
185
                rc = PTR_ERR(file);
186
                goto failed;
187
        }
188
 
189
        /* physical cpus */
190
        dir = hypfs_mkdir(sb, root, "cpus");
191
        if (IS_ERR(dir)) {
192
                rc = PTR_ERR(dir);
193
                goto failed;
194
        }
195
        file = hypfs_create_u64(sb, dir, "count", data->lcpus);
196
        if (IS_ERR(file)) {
197
                rc = PTR_ERR(file);
198
                goto failed;
199
        }
200
 
201
        /* guests */
202
        dir = hypfs_mkdir(sb, root, "systems");
203
        if (IS_ERR(dir)) {
204
                rc = PTR_ERR(dir);
205
                goto failed;
206
        }
207
 
208
        for (i = 0; i < count; i++) {
209
                rc = hpyfs_vm_create_guest(sb, dir, &(data[i]));
210
                if (rc)
211
                        goto failed;
212
        }
213
        diag2fc_free(data);
214
        return 0;
215
 
216
failed:
217
        diag2fc_free(data);
218
        return rc;
219
}
220
 
221
int hypfs_vm_init(void)
222
{
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;
227
        else
228
                return -EACCES;
229
 
230
        return 0;
231
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.