debuggers.hg

annotate xen/common/perfc.c @ 22855:1d1eec7e1fb4

xl: Perform minimal validation of virtual disk file while parsing config file

This patch performs some very basic validation on the virtual disk
file passed through the config file. This validation ensures that we
don't go too far with the initialization like spawn qemu and more
while there could be some potentially fundamental issues.

[ Patch fixed up to work with PHYSTYPE_EMPTY 22808:6ec61438713a -iwj ]

Signed-off-by: Kamala Narasimhan <kamala.narasimhan@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Committed-by: Ian Jackson <ian.jackson@eu.citrix.com>
author Kamala Narasimhan <kamala.narasimhan@gmail.com>
date Tue Jan 25 18:09:49 2011 +0000 (2011-01-25)
parents 6348b2ab5c39
children
rev   line source
iap10@274 1
kaf24@1248 2 #include <xen/lib.h>
kaf24@1248 3 #include <xen/smp.h>
kaf24@1248 4 #include <xen/time.h>
kaf24@1248 5 #include <xen/perfc.h>
kaf24@1248 6 #include <xen/keyhandler.h>
mafetter@4857 7 #include <xen/spinlock.h>
kaf24@9166 8 #include <xen/mm.h>
kaf24@9166 9 #include <xen/guest_access.h>
steven@11310 10 #include <public/sysctl.h>
kaf24@10992 11 #include <asm/perfc.h>
iap10@274 12
kaf24@701 13 #define PERFCOUNTER( var, name ) { name, TYPE_SINGLE, 0 },
kaf24@701 14 #define PERFCOUNTER_ARRAY( var, name, size ) { name, TYPE_ARRAY, size },
iap10@1240 15 #define PERFSTATUS( var, name ) { name, TYPE_S_SINGLE, 0 },
iap10@1240 16 #define PERFSTATUS_ARRAY( var, name, size ) { name, TYPE_S_ARRAY, size },
kfraser@14624 17 static const struct {
kfraser@14624 18 const char *name;
kfraser@14624 19 enum { TYPE_SINGLE, TYPE_ARRAY,
kfraser@14624 20 TYPE_S_SINGLE, TYPE_S_ARRAY
iap10@1240 21 } type;
kfraser@14624 22 unsigned int nr_elements;
kaf24@701 23 } perfc_info[] = {
kaf24@1248 24 #include <xen/perfc_defn.h>
iap10@274 25 };
iap10@274 26
kaf24@701 27 #define NR_PERFCTRS (sizeof(perfc_info) / sizeof(perfc_info[0]))
kaf24@701 28
kfraser@14624 29 DEFINE_PER_CPU(perfc_t[NUM_PERFCOUNTERS], perfcounters);
iap10@274 30
kaf24@2842 31 void perfc_printall(unsigned char key)
iap10@274 32 {
kfraser@14624 33 unsigned int i, j;
rn@328 34 s_time_t now = NOW();
iap10@274 35
kaf24@701 36 printk("Xen performance counters SHOW (now = 0x%08X:%08X)\n",
kaf24@701 37 (u32)(now>>32), (u32)now);
rn@328 38
kfraser@14624 39 for ( i = j = 0; i < NR_PERFCTRS; i++ )
kaf24@701 40 {
kfraser@14624 41 unsigned int k, cpu;
kfraser@14624 42 unsigned long long sum = 0;
kfraser@14624 43
kaf24@717 44 printk("%-32s ", perfc_info[i].name);
kaf24@701 45 switch ( perfc_info[i].type )
kaf24@701 46 {
kaf24@701 47 case TYPE_SINGLE:
iap10@1240 48 case TYPE_S_SINGLE:
kfraser@14624 49 for_each_online_cpu ( cpu )
kfraser@14624 50 sum += per_cpu(perfcounters, cpu)[j];
Tim@14939 51 if ( perfc_info[i].type == TYPE_S_SINGLE )
Tim@14939 52 sum = (perfc_t) sum;
kfraser@14624 53 printk("TOTAL[%12Lu]", sum);
kfraser@14624 54 if ( sum )
kaf24@9947 55 {
kfraser@14624 56 k = 0;
kfraser@14624 57 for_each_online_cpu ( cpu )
kfraser@14624 58 {
kfraser@14624 59 if ( k > 0 && (k % 4) == 0 )
kfraser@14624 60 printk("\n%46s", "");
kfraser@14624 61 printk(" CPU%02u[%10"PRIperfc"u]", cpu, per_cpu(perfcounters, cpu)[j]);
kfraser@14624 62 ++k;
kfraser@14624 63 }
kaf24@9947 64 }
kfraser@14624 65 ++j;
kaf24@701 66 break;
kaf24@701 67 case TYPE_ARRAY:
iap10@1240 68 case TYPE_S_ARRAY:
kfraser@14624 69 for_each_online_cpu ( cpu )
kfraser@14624 70 {
kfraser@14624 71 perfc_t *counters = per_cpu(perfcounters, cpu) + j;
kfraser@14624 72
kfraser@14624 73 for ( k = 0; k < perfc_info[i].nr_elements; k++ )
kfraser@14624 74 sum += counters[k];
kfraser@14624 75 }
Tim@14939 76 if ( perfc_info[i].type == TYPE_S_ARRAY )
Tim@14939 77 sum = (perfc_t) sum;
kfraser@14624 78 printk("TOTAL[%12Lu]", sum);
kaf24@9947 79 if (sum)
mafetter@4861 80 {
kfraser@14624 81 #ifdef PERF_ARRAYS
kfraser@14624 82 for ( k = 0; k < perfc_info[i].nr_elements; k++ )
kfraser@14624 83 {
kfraser@14624 84 sum = 0;
kfraser@14624 85 for_each_online_cpu ( cpu )
kfraser@14624 86 sum += per_cpu(perfcounters, cpu)[j + k];
Tim@14939 87 if ( perfc_info[i].type == TYPE_S_ARRAY )
Tim@14939 88 sum = (perfc_t) sum;
kfraser@14624 89 if ( (k % 4) == 0 )
kfraser@14624 90 printk("\n%16s", "");
kfraser@14624 91 printk(" ARR%02u[%10Lu]", k, sum);
kfraser@14624 92 }
kfraser@14624 93 #else
kfraser@14624 94 k = 0;
kfraser@14624 95 for_each_online_cpu ( cpu )
kaf24@9947 96 {
kfraser@14624 97 perfc_t *counters = per_cpu(perfcounters, cpu) + j;
kfraser@14624 98 unsigned int n;
kfraser@14624 99
kfraser@14624 100 sum = 0;
kfraser@14624 101 for ( n = 0; n < perfc_info[i].nr_elements; n++ )
kfraser@14624 102 sum += counters[n];
Tim@14939 103 if ( perfc_info[i].type == TYPE_S_ARRAY )
Tim@14939 104 sum = (perfc_t) sum;
kfraser@14624 105 if ( k > 0 && (k % 4) == 0 )
kfraser@14624 106 printk("\n%46s", "");
kfraser@14624 107 printk(" CPU%02u[%10Lu]", cpu, sum);
kfraser@14624 108 ++k;
kaf24@9947 109 }
kfraser@14624 110 #endif
mafetter@4861 111 }
kfraser@14624 112 j += perfc_info[i].nr_elements;
kaf24@701 113 break;
rn@328 114 }
kaf24@712 115 printk("\n");
iap10@274 116 }
rn@328 117 }
iap10@274 118
kaf24@2842 119 void perfc_reset(unsigned char key)
rn@328 120 {
kaf24@9947 121 unsigned int i, j;
rn@328 122 s_time_t now = NOW();
iap10@1240 123
kaf24@3269 124 if ( key != '\0' )
kaf24@3269 125 printk("Xen performance counters RESET (now = 0x%08X:%08X)\n",
kaf24@3269 126 (u32)(now>>32), (u32)now);
iap10@1240 127
kaf24@2842 128 /* leave STATUS counters alone -- don't reset */
iap10@1240 129
kfraser@14624 130 for ( i = j = 0; i < NR_PERFCTRS; i++ )
iap10@1240 131 {
kfraser@14624 132 unsigned int cpu;
kfraser@14624 133
iap10@1240 134 switch ( perfc_info[i].type )
iap10@1240 135 {
iap10@1240 136 case TYPE_SINGLE:
keir@21436 137 for_each_online_cpu ( cpu )
kfraser@14624 138 per_cpu(perfcounters, cpu)[j] = 0;
iap10@1240 139 case TYPE_S_SINGLE:
kfraser@14624 140 ++j;
iap10@1240 141 break;
iap10@1240 142 case TYPE_ARRAY:
keir@21436 143 for_each_online_cpu ( cpu )
kfraser@14624 144 memset(per_cpu(perfcounters, cpu) + j, 0,
kfraser@14624 145 perfc_info[i].nr_elements * sizeof(perfc_t));
iap10@1240 146 case TYPE_S_ARRAY:
kfraser@14624 147 j += perfc_info[i].nr_elements;
iap10@1240 148 break;
iap10@1240 149 }
iap10@1240 150 }
iap10@6173 151
kfraser@14624 152 arch_perfc_reset();
iap10@274 153 }
rn@328 154
steven@11310 155 static xen_sysctl_perfc_desc_t perfc_d[NR_PERFCTRS];
steven@11310 156 static xen_sysctl_perfc_val_t *perfc_vals;
kfraser@14624 157 static unsigned int perfc_nbr_vals;
keir@21436 158 static cpumask_t perfc_cpumap;
keir@21436 159
keir@14458 160 static int perfc_copy_info(XEN_GUEST_HANDLE_64(xen_sysctl_perfc_desc_t) desc,
keir@14458 161 XEN_GUEST_HANDLE_64(xen_sysctl_perfc_val_t) val)
kaf24@3269 162 {
kfraser@14624 163 unsigned int i, j, v;
kaf24@3269 164
kaf24@3269 165 /* We only copy the name and array-size information once. */
keir@21436 166 if ( !cpus_equal(cpu_online_map, perfc_cpumap) )
kaf24@3269 167 {
keir@21436 168 unsigned int nr_cpus;
keir@21436 169 perfc_cpumap = cpu_online_map;
keir@21436 170 nr_cpus = cpus_weight(perfc_cpumap);
keir@21436 171
keir@21436 172 perfc_nbr_vals = 0;
keir@21436 173
kaf24@3269 174 for ( i = 0; i < NR_PERFCTRS; i++ )
kaf24@3269 175 {
kfraser@13701 176 safe_strcpy(perfc_d[i].name, perfc_info[i].name);
kaf24@3269 177
kaf24@3269 178 switch ( perfc_info[i].type )
kaf24@3269 179 {
kaf24@3269 180 case TYPE_SINGLE:
kaf24@3269 181 case TYPE_S_SINGLE:
keir@21436 182 perfc_d[i].nr_vals = nr_cpus;
kaf24@3269 183 break;
kaf24@3269 184 case TYPE_ARRAY:
kaf24@3269 185 case TYPE_S_ARRAY:
kaf24@3269 186 perfc_d[i].nr_vals = perfc_info[i].nr_elements;
kaf24@3269 187 break;
kaf24@3269 188 }
kaf24@10991 189 perfc_nbr_vals += perfc_d[i].nr_vals;
kaf24@3269 190 }
keir@21436 191
keir@21436 192 xfree(perfc_vals);
steven@11310 193 perfc_vals = xmalloc_array(xen_sysctl_perfc_val_t, perfc_nbr_vals);
kaf24@3269 194 }
kaf24@12052 195
kaf24@12052 196 if ( guest_handle_is_null(desc) )
kaf24@12052 197 return 0;
kaf24@12052 198
kaf24@12052 199 if ( perfc_vals == NULL )
kaf24@10991 200 return -ENOMEM;
kaf24@3269 201
kaf24@10992 202 /* Architecture may fill counters from hardware. */
kaf24@10992 203 arch_perfc_gather();
kaf24@10992 204
kaf24@3269 205 /* We gather the counts together every time. */
kfraser@14624 206 for ( i = j = v = 0; i < NR_PERFCTRS; i++ )
kaf24@3269 207 {
kfraser@14624 208 unsigned int cpu;
kfraser@14624 209
kaf24@3269 210 switch ( perfc_info[i].type )
kaf24@3269 211 {
kaf24@3269 212 case TYPE_SINGLE:
kaf24@3269 213 case TYPE_S_SINGLE:
keir@21436 214 for_each_cpu_mask ( cpu, perfc_cpumap )
kfraser@14624 215 perfc_vals[v++] = per_cpu(perfcounters, cpu)[j];
kfraser@14624 216 ++j;
kaf24@3269 217 break;
kaf24@3269 218 case TYPE_ARRAY:
kaf24@3269 219 case TYPE_S_ARRAY:
kfraser@14624 220 memset(perfc_vals + v, 0, perfc_d[i].nr_vals * sizeof(*perfc_vals));
keir@21436 221 for_each_cpu_mask ( cpu, perfc_cpumap )
kfraser@14624 222 {
kfraser@14624 223 perfc_t *counters = per_cpu(perfcounters, cpu) + j;
kfraser@14624 224 unsigned int k;
kfraser@14624 225
kfraser@14624 226 for ( k = 0; k < perfc_d[i].nr_vals; k++ )
kfraser@14624 227 perfc_vals[v + k] += counters[k];
kfraser@14624 228 }
kfraser@14624 229 v += perfc_d[i].nr_vals;
kfraser@14624 230 j += perfc_info[i].nr_elements;
kaf24@3269 231 break;
kaf24@3269 232 }
kaf24@3269 233 }
kaf24@10991 234 BUG_ON(v != perfc_nbr_vals);
kaf24@3269 235
kfraser@15437 236 if ( copy_to_guest(desc, perfc_d, NR_PERFCTRS) )
kaf24@10991 237 return -EFAULT;
kaf24@12052 238 if ( copy_to_guest(val, perfc_vals, perfc_nbr_vals) )
kaf24@10991 239 return -EFAULT;
kaf24@10991 240 return 0;
kaf24@3269 241 }
kaf24@3269 242
kaf24@3269 243 /* Dom0 control of perf counters */
steven@11310 244 int perfc_control(xen_sysctl_perfc_op_t *pc)
kaf24@3269 245 {
kaf24@10288 246 static DEFINE_SPINLOCK(lock);
kaf24@3269 247 int rc;
kaf24@3269 248
kaf24@3269 249 spin_lock(&lock);
kaf24@3269 250
kfraser@11295 251 switch ( pc->cmd )
kaf24@3269 252 {
kfraser@11295 253 case XEN_SYSCTL_PERFCOP_reset:
kfraser@14624 254 rc = perfc_copy_info(pc->desc, pc->val);
kaf24@3269 255 perfc_reset(0);
kaf24@3269 256 break;
kaf24@3269 257
kfraser@11295 258 case XEN_SYSCTL_PERFCOP_query:
kfraser@14624 259 rc = perfc_copy_info(pc->desc, pc->val);
kaf24@3269 260 break;
kaf24@3269 261
kaf24@3269 262 default:
kaf24@3269 263 rc = -EINVAL;
kaf24@3269 264 break;
kaf24@3269 265 }
kaf24@3269 266
kaf24@3269 267 spin_unlock(&lock);
kaf24@3269 268
kaf24@10991 269 pc->nr_counters = NR_PERFCTRS;
kaf24@10991 270 pc->nr_vals = perfc_nbr_vals;
kaf24@10991 271
kaf24@3269 272 return rc;
kaf24@3269 273 }
kaf24@3952 274
kaf24@3952 275 /*
kaf24@3952 276 * Local variables:
kaf24@3952 277 * mode: C
kaf24@3952 278 * c-set-style: "BSD"
kaf24@3952 279 * c-basic-offset: 4
kaf24@3952 280 * tab-width: 4
kaf24@3952 281 * indent-tabs-mode: nil
kaf24@4026 282 * End:
kaf24@3952 283 */