aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/oprofile/nmi_int.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/oprofile/nmi_int.c')
-rw-r--r--arch/i386/oprofile/nmi_int.c41
1 files changed, 29 insertions, 12 deletions
diff --git a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c
index 5f8dc8a21bd7..8710ca081b1e 100644
--- a/arch/i386/oprofile/nmi_int.c
+++ b/arch/i386/oprofile/nmi_int.c
@@ -98,15 +98,19 @@ static void nmi_cpu_save_registers(struct op_msrs * msrs)
98 unsigned int i; 98 unsigned int i;
99 99
100 for (i = 0; i < nr_ctrs; ++i) { 100 for (i = 0; i < nr_ctrs; ++i) {
101 rdmsr(counters[i].addr, 101 if (counters[i].addr){
102 counters[i].saved.low, 102 rdmsr(counters[i].addr,
103 counters[i].saved.high); 103 counters[i].saved.low,
104 counters[i].saved.high);
105 }
104 } 106 }
105 107
106 for (i = 0; i < nr_ctrls; ++i) { 108 for (i = 0; i < nr_ctrls; ++i) {
107 rdmsr(controls[i].addr, 109 if (controls[i].addr){
108 controls[i].saved.low, 110 rdmsr(controls[i].addr,
109 controls[i].saved.high); 111 controls[i].saved.low,
112 controls[i].saved.high);
113 }
110 } 114 }
111} 115}
112 116
@@ -205,15 +209,19 @@ static void nmi_restore_registers(struct op_msrs * msrs)
205 unsigned int i; 209 unsigned int i;
206 210
207 for (i = 0; i < nr_ctrls; ++i) { 211 for (i = 0; i < nr_ctrls; ++i) {
208 wrmsr(controls[i].addr, 212 if (controls[i].addr){
209 controls[i].saved.low, 213 wrmsr(controls[i].addr,
210 controls[i].saved.high); 214 controls[i].saved.low,
215 controls[i].saved.high);
216 }
211 } 217 }
212 218
213 for (i = 0; i < nr_ctrs; ++i) { 219 for (i = 0; i < nr_ctrs; ++i) {
214 wrmsr(counters[i].addr, 220 if (counters[i].addr){
215 counters[i].saved.low, 221 wrmsr(counters[i].addr,
216 counters[i].saved.high); 222 counters[i].saved.low,
223 counters[i].saved.high);
224 }
217 } 225 }
218} 226}
219 227
@@ -234,6 +242,7 @@ static void nmi_cpu_shutdown(void * dummy)
234 apic_write(APIC_LVTPC, saved_lvtpc[cpu]); 242 apic_write(APIC_LVTPC, saved_lvtpc[cpu]);
235 apic_write(APIC_LVTERR, v); 243 apic_write(APIC_LVTERR, v);
236 nmi_restore_registers(msrs); 244 nmi_restore_registers(msrs);
245 model->shutdown(msrs);
237} 246}
238 247
239 248
@@ -284,6 +293,14 @@ static int nmi_create_files(struct super_block * sb, struct dentry * root)
284 struct dentry * dir; 293 struct dentry * dir;
285 char buf[4]; 294 char buf[4];
286 295
296 /* quick little hack to _not_ expose a counter if it is not
297 * available for use. This should protect userspace app.
298 * NOTE: assumes 1:1 mapping here (that counters are organized
299 * sequentially in their struct assignment).
300 */
301 if (unlikely(!avail_to_resrv_perfctr_nmi_bit(i)))
302 continue;
303
287 snprintf(buf, sizeof(buf), "%d", i); 304 snprintf(buf, sizeof(buf), "%d", i);
288 dir = oprofilefs_mkdir(sb, root, buf); 305 dir = oprofilefs_mkdir(sb, root, buf);
289 oprofilefs_create_ulong(sb, dir, "enabled", &counter_config[i].enabled); 306 oprofilefs_create_ulong(sb, dir, "enabled", &counter_config[i].enabled);