Coverage Report

Created: 2017-10-25 09:10

/root/src/xen/xen/arch/x86/oprofile/nmi_int.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * @file nmi_int.c
3
 *
4
 * @remark Copyright 2002 OProfile authors
5
 * @remark Read the file COPYING
6
 *
7
 * @author John Levon <levon@movementarian.org>
8
 *
9
 * Modified for Xen: by Aravind Menon & Jose Renato Santos
10
 *   These modifications are:
11
 *   Copyright (C) 2005 Hewlett-Packard Co.
12
 */
13
14
#include <xen/event.h>
15
#include <xen/types.h>
16
#include <xen/errno.h>
17
#include <xen/init.h>
18
#include <xen/string.h>
19
#include <xen/delay.h>
20
#include <xen/xenoprof.h>
21
#include <public/xen.h>
22
#include <asm/msr.h>
23
#include <asm/apic.h>
24
#include <asm/regs.h>
25
#include <asm/current.h>
26
#include <asm/nmi.h>
27
28
#include "op_counter.h"
29
#include "op_x86_model.h"
30
31
struct op_counter_config counter_config[OP_MAX_COUNTER];
32
struct op_ibs_config ibs_config;
33
34
struct op_x86_model_spec const *__read_mostly model;
35
static struct op_msrs cpu_msrs[NR_CPUS];
36
static unsigned long saved_lvtpc[NR_CPUS];
37
38
static char *cpu_type;
39
40
static int passive_domain_msr_op_checks(unsigned int msr, int *typep, int *indexp)
41
50
{
42
50
  struct vpmu_struct *vpmu = vcpu_vpmu(current);
43
50
  if ( model == NULL )
44
0
    return 0;
45
50
  if ( model->is_arch_pmu_msr == NULL )
46
0
    return 0;
47
50
  if ( !model->is_arch_pmu_msr(msr, typep, indexp) )
48
50
    return 0;
49
50
50
0
  if ( !vpmu_is_set(vpmu, VPMU_PASSIVE_DOMAIN_ALLOCATED) )
51
0
    if ( ! model->allocated_msr(current) )
52
0
      return 0;
53
0
  return 1;
54
0
}
55
56
int passive_domain_do_rdmsr(unsigned int msr, uint64_t *msr_content)
57
0
{
58
0
  int type, index;
59
0
60
0
  if ( !passive_domain_msr_op_checks(msr, &type, &index))
61
0
    return 0;
62
0
63
0
  model->load_msr(current, type, index, msr_content);
64
0
  return 1;
65
0
}
66
67
int passive_domain_do_wrmsr(unsigned int msr, uint64_t msr_content)
68
50
{
69
50
  int type, index;
70
50
71
50
  if ( !passive_domain_msr_op_checks(msr, &type, &index))
72
50
    return 0;
73
50
74
0
  model->save_msr(current, type, index, msr_content);
75
0
  return 1;
76
50
}
77
78
void passive_domain_destroy(struct vcpu *v)
79
0
{
80
0
  struct vpmu_struct *vpmu = vcpu_vpmu(v);
81
0
  if ( vpmu_is_set(vpmu, VPMU_PASSIVE_DOMAIN_ALLOCATED) )
82
0
    model->free_msr(v);
83
0
}
84
85
static int nmi_callback(const struct cpu_user_regs *regs, int cpu)
86
0
{
87
0
  int xen_mode, ovf;
88
0
89
0
  ovf = model->check_ctrs(cpu, &cpu_msrs[cpu], regs);
90
0
  xen_mode = ring_0(regs);
91
0
  if ( ovf && is_active(current->domain) && !xen_mode )
92
0
    send_guest_vcpu_virq(current, VIRQ_XENOPROF);
93
0
94
0
  if ( ovf == 2 )
95
0
                current->nmi_pending = 1;
96
0
  return 1;
97
0
}
98
99
100
static void nmi_cpu_save_registers(struct op_msrs *msrs)
101
0
{
102
0
  unsigned int const nr_ctrs = model->num_counters;
103
0
  unsigned int const nr_ctrls = model->num_controls;
104
0
  struct op_msr *counters = msrs->counters;
105
0
  struct op_msr *controls = msrs->controls;
106
0
  unsigned int i;
107
0
108
0
  for (i = 0; i < nr_ctrs; ++i) {
109
0
    rdmsrl(counters[i].addr, counters[i].value);
110
0
  }
111
0
112
0
  for (i = 0; i < nr_ctrls; ++i) {
113
0
    rdmsrl(controls[i].addr, controls[i].value);
114
0
  }
115
0
}
116
117
118
static void nmi_save_registers(void * dummy)
119
0
{
120
0
  int cpu = smp_processor_id();
121
0
  struct op_msrs * msrs = &cpu_msrs[cpu];
122
0
  model->fill_in_addresses(msrs);
123
0
  nmi_cpu_save_registers(msrs);
124
0
}
125
126
127
static void free_msrs(void)
128
0
{
129
0
  int i;
130
0
  for (i = 0; i < nr_cpu_ids; ++i) {
131
0
    xfree(cpu_msrs[i].counters);
132
0
    cpu_msrs[i].counters = NULL;
133
0
    xfree(cpu_msrs[i].controls);
134
0
    cpu_msrs[i].controls = NULL;
135
0
  }
136
0
}
137
138
139
static int allocate_msrs(void)
140
0
{
141
0
  int success = 1;
142
0
  size_t controls_size = sizeof(struct op_msr) * model->num_controls;
143
0
  size_t counters_size = sizeof(struct op_msr) * model->num_counters;
144
0
145
0
  int i;
146
0
  for_each_online_cpu (i) {
147
0
    cpu_msrs[i].counters = xmalloc_bytes(counters_size);
148
0
    if (!cpu_msrs[i].counters) {
149
0
      success = 0;
150
0
      break;
151
0
    }
152
0
    cpu_msrs[i].controls = xmalloc_bytes(controls_size);
153
0
    if (!cpu_msrs[i].controls) {
154
0
      success = 0;
155
0
      break;
156
0
    }
157
0
  }
158
0
159
0
  if (!success)
160
0
    free_msrs();
161
0
162
0
  return success;
163
0
}
164
165
166
static void nmi_cpu_setup(void * dummy)
167
0
{
168
0
  int cpu = smp_processor_id();
169
0
  struct op_msrs * msrs = &cpu_msrs[cpu];
170
0
  model->setup_ctrs(msrs);
171
0
}
172
173
174
int nmi_setup_events(void)
175
0
{
176
0
  on_each_cpu(nmi_cpu_setup, NULL, 1);
177
0
  return 0;
178
0
}
179
180
int nmi_reserve_counters(void)
181
0
{
182
0
  if (!allocate_msrs())
183
0
    return -ENOMEM;
184
0
185
0
  /* We walk a thin line between law and rape here.
186
0
   * We need to be careful to install our NMI handler
187
0
   * without actually triggering any NMIs as this will
188
0
   * break the core code horrifically.
189
0
   */
190
0
  if (reserve_lapic_nmi() < 0) {
191
0
    free_msrs();
192
0
    return -EBUSY;
193
0
  }
194
0
  /* We need to serialize save and setup for HT because the subset
195
0
   * of msrs are distinct for save and setup operations
196
0
   */
197
0
  on_each_cpu(nmi_save_registers, NULL, 1);
198
0
  return 0;
199
0
}
200
201
int nmi_enable_virq(void)
202
0
{
203
0
  set_nmi_callback(nmi_callback);
204
0
  return 0;
205
0
}
206
207
208
void nmi_disable_virq(void)
209
0
{
210
0
  unset_nmi_callback();
211
0
}
212
213
214
static void nmi_restore_registers(struct op_msrs * msrs)
215
0
{
216
0
  unsigned int const nr_ctrs = model->num_counters;
217
0
  unsigned int const nr_ctrls = model->num_controls;
218
0
  struct op_msr * counters = msrs->counters;
219
0
  struct op_msr * controls = msrs->controls;
220
0
  unsigned int i;
221
0
222
0
  for (i = 0; i < nr_ctrls; ++i) {
223
0
    wrmsrl(controls[i].addr, controls[i].value);
224
0
  }
225
0
226
0
  for (i = 0; i < nr_ctrs; ++i) {
227
0
    wrmsrl(counters[i].addr, counters[i].value);
228
0
  }
229
0
}
230
231
232
static void nmi_cpu_shutdown(void * dummy)
233
0
{
234
0
  int cpu = smp_processor_id();
235
0
  struct op_msrs * msrs = &cpu_msrs[cpu];
236
0
  nmi_restore_registers(msrs);
237
0
}
238
239
240
void nmi_release_counters(void)
241
0
{
242
0
  on_each_cpu(nmi_cpu_shutdown, NULL, 1);
243
0
  release_lapic_nmi();
244
0
  free_msrs();
245
0
}
246
247
248
static void nmi_cpu_start(void * dummy)
249
0
{
250
0
  int cpu = smp_processor_id();
251
0
  struct op_msrs const * msrs = &cpu_msrs[cpu];
252
0
  saved_lvtpc[cpu] = apic_read(APIC_LVTPC);
253
0
  apic_write(APIC_LVTPC, APIC_DM_NMI);
254
0
  model->start(msrs);
255
0
}
256
257
258
int nmi_start(void)
259
0
{
260
0
  on_each_cpu(nmi_cpu_start, NULL, 1);
261
0
  return 0;
262
0
}
263
264
265
static void nmi_cpu_stop(void * dummy)
266
0
{
267
0
  unsigned int v;
268
0
  int cpu = smp_processor_id();
269
0
  struct op_msrs const * msrs = &cpu_msrs[cpu];
270
0
  model->stop(msrs);
271
0
272
0
  /* restoring APIC_LVTPC can trigger an apic error because the delivery
273
0
   * mode and vector nr combination can be illegal. That's by design: on
274
0
   * power on apic lvt contain a zero vector nr which are legal only for
275
0
   * NMI delivery mode. So inhibit apic err before restoring lvtpc
276
0
   */
277
0
  if ( (apic_read(APIC_LVTPC) & APIC_MODE_MASK) != APIC_DM_NMI
278
0
       || (apic_read(APIC_LVTPC) & APIC_LVT_MASKED) )
279
0
  {
280
0
    printk("nmi_stop: APIC not good %ul\n", apic_read(APIC_LVTPC));
281
0
    mdelay(5000);
282
0
  }
283
0
  v = apic_read(APIC_LVTERR);
284
0
  apic_write(APIC_LVTERR, v | APIC_LVT_MASKED);
285
0
  apic_write(APIC_LVTPC, saved_lvtpc[cpu]);
286
0
  apic_write(APIC_LVTERR, v);
287
0
}
288
289
290
void nmi_stop(void)
291
0
{
292
0
  on_each_cpu(nmi_cpu_stop, NULL, 1);
293
0
}
294
295
296
static int __init p4_init(char ** cpu_type)
297
0
{
298
0
  __u8 cpu_model = current_cpu_data.x86_model;
299
0
300
0
  if ((cpu_model > 6) || (cpu_model == 5)) {
301
0
    printk("xenoprof: Initialization failed. "
302
0
           "Intel processor model %d for pentium 4 family is not "
303
0
           "supported\n", cpu_model);
304
0
    return 0;
305
0
  }
306
0
307
0
  switch (current_cpu_data.x86_num_siblings) {
308
0
    case 1:
309
0
      *cpu_type = "i386/p4";
310
0
      model = &op_p4_spec;
311
0
      return 1;
312
0
313
0
    case 2:
314
0
      *cpu_type = "i386/p4-ht";
315
0
      model = &op_p4_ht2_spec;
316
0
      return 1;
317
0
  }
318
0
319
0
  printk("Xenoprof ERROR: P4 HyperThreading detected with > 2 threads\n");
320
0
321
0
  return 0;
322
0
}
323
324
325
static int force_arch_perfmon;
326
327
static int force_cpu_type(const char *str)
328
0
{
329
0
  if (!strcmp(str, "arch_perfmon")) {
330
0
    force_arch_perfmon = 1;
331
0
    printk(KERN_INFO "oprofile: forcing architectural perfmon\n");
332
0
  }
333
0
  else
334
0
    return -EINVAL;
335
0
336
0
  return 0;
337
0
}
338
custom_param("cpu_type", force_cpu_type);
339
340
static int __init ppro_init(char ** cpu_type)
341
1
{
342
1
  __u8 cpu_model = current_cpu_data.x86_model;
343
1
344
1
  if (force_arch_perfmon && cpu_has_arch_perfmon)
345
0
    return 0;
346
1
347
1
  switch (cpu_model) {
348
0
  case 14:
349
0
    *cpu_type = "i386/core";
350
0
    break;
351
0
  case 15:
352
0
    *cpu_type = "i386/core_2";
353
0
    ppro_has_global_ctrl = 1;
354
0
    break;
355
1
  default:
356
1
    /* Unknown */
357
1
    return 0;
358
1
  }
359
1
360
0
  model = &op_ppro_spec;
361
0
  return 1;
362
1
}
363
364
static int __init arch_perfmon_init(char **cpu_type)
365
1
{
366
1
  if (!cpu_has_arch_perfmon)
367
0
    return 0;
368
1
  *cpu_type = "i386/arch_perfmon";
369
1
  model = &op_arch_perfmon_spec;
370
1
  arch_perfmon_setup_counters();
371
1
  ppro_has_global_ctrl = 1;
372
1
  return 1;
373
1
}
374
375
static int __init nmi_init(void)
376
1
{
377
1
  __u8 vendor = current_cpu_data.x86_vendor;
378
1
  __u8 family = current_cpu_data.x86;
379
1
  __u8 _model = current_cpu_data.x86_model;
380
1
381
1
  if (!cpu_has_apic) {
382
0
    printk("xenoprof: Initialization failed. No APIC\n");
383
0
    return -ENODEV;
384
0
  }
385
1
386
1
  switch (vendor) {
387
0
    case X86_VENDOR_AMD:
388
0
      /* Needs to be at least an Athlon (or hammer in 32bit mode) */
389
0
390
0
      switch (family) {
391
0
      default:
392
0
        printk("xenoprof: Initialization failed. "
393
0
               "AMD processor family %d is not "
394
0
               "supported\n", family);
395
0
        return -ENODEV;
396
0
      case 0xf:
397
0
        model = &op_athlon_spec;
398
0
        cpu_type = "x86-64/hammer";
399
0
        break;
400
0
      case 0x10:
401
0
        model = &op_athlon_spec;
402
0
        cpu_type = "x86-64/family10";
403
0
        ibs_init();
404
0
        break;
405
0
      case 0x11:
406
0
        model = &op_athlon_spec;
407
0
        cpu_type = "x86-64/family11h";
408
0
        break;
409
0
                        case 0x12:
410
0
        model = &op_athlon_spec;
411
0
        cpu_type = "x86-64/family12h";
412
0
        break;
413
0
      case 0x14:
414
0
                                model = &op_athlon_spec;
415
0
                                cpu_type = "x86-64/family14h";
416
0
                                break;
417
0
                        case 0x15:
418
0
                                model = &op_amd_fam15h_spec;
419
0
                                cpu_type = "x86-64/family15h";
420
0
                                break;
421
0
      case 0x16:
422
0
        model = &op_athlon_spec;
423
0
        cpu_type = "x86-64/family16h";
424
0
        break;
425
0
      }
426
0
      break;
427
0
428
1
    case X86_VENDOR_INTEL:
429
1
      switch (family) {
430
1
        /* Pentium IV */
431
0
        case 0xf:
432
0
          p4_init(&cpu_type);
433
0
          break;
434
0
435
0
        /* A P6-class processor */
436
1
        case 6:
437
1
          ppro_init(&cpu_type);
438
1
          break;
439
0
440
0
        default:
441
0
        break;
442
1
      }
443
1
      if (!cpu_type && !arch_perfmon_init(&cpu_type)) {
444
0
        printk("xenoprof: Initialization failed. "
445
0
               "Intel processor family %d model %d "
446
0
               "is not supported\n", family, _model);
447
0
        return -ENODEV;
448
0
      }
449
1
      break;
450
1
451
0
    default:
452
0
      printk("xenoprof: Initialization failed. "
453
0
             "Unsupported processor. Unknown vendor %d\n",
454
0
        vendor);
455
0
      return -ENODEV;
456
1
  }
457
1
458
1
  return 0;
459
1
}
460
461
__initcall(nmi_init);
462
463
int xenoprof_arch_init(int *num_events, char *_cpu_type)
464
0
{
465
0
  if (cpu_type == NULL)
466
0
    return -ENODEV;
467
0
  *num_events = model->num_counters;
468
0
  strlcpy(_cpu_type, cpu_type, XENOPROF_CPU_TYPE_SIZE);
469
0
  return 0;
470
0
}