1 /**
2  * @file op_model_ppro.h
3  * pentium pro / P6 model-specific MSR operations
4  *
5  * @remark Copyright 2002 OProfile authors
6  * @remark Read the file COPYING
7  *
8  * @author John Levon
9  * @author Philippe Elie
10  * @author Graydon Hoare
11  */
12 
13 #include <xen/types.h>
14 #include <xen/xenoprof.h>
15 #include <xen/sched.h>
16 #include <asm/msr.h>
17 #include <asm/io.h>
18 #include <asm/apic.h>
19 #include <asm/processor.h>
20 #include <asm/regs.h>
21 #include <asm/current.h>
22 #include <asm/vpmu.h>
23 
24 #include "op_x86_model.h"
25 #include "op_counter.h"
26 
27 struct arch_msr_pair {
28     u64 counter;
29     u64 control;
30 };
31 
32 /*
33  * Intel "Architectural Performance Monitoring" CPUID
34  * detection/enumeration details:
35  */
36 union cpuid10_eax {
37 	struct {
38 		unsigned int version_id:8;
39 		unsigned int num_counters:8;
40 		unsigned int bit_width:8;
41 		unsigned int mask_length:8;
42 	} split;
43 	unsigned int full;
44 };
45 
46 static int num_counters = 2;
47 static int counter_width = 32;
48 
49 #define CTR_OVERFLOWED(n) (!((n) & (1ULL<<(counter_width-1))))
50 
51 #define CTRL_READ(msr_content,msrs,c) do {rdmsrl((msrs->controls[(c)].addr), (msr_content));} while (0)
52 #define CTRL_WRITE(msr_content,msrs,c) do {wrmsrl((msrs->controls[(c)].addr), (msr_content));} while (0)
53 #define CTRL_SET_ACTIVE(n) (n |= (1ULL<<22))
54 #define CTRL_SET_INACTIVE(n) (n &= ~(1ULL<<22))
55 #define CTRL_CLEAR(x) (x &= (1ULL<<21))
56 #define CTRL_SET_ENABLE(val) (val |= 1ULL<<20)
57 #define CTRL_SET_USR(val,u) (val |= ((u & 1ULL) << 16))
58 #define CTRL_SET_KERN(val,k) (val |= ((k & 1ULL) << 17))
59 #define CTRL_SET_UM(val, m) (val |= (m << 8))
60 #define CTRL_SET_EVENT(val, e) (val |= e)
61 #define IS_ACTIVE(val) (val & (1ULL << 22) )
62 #define IS_ENABLE(val) (val & (1ULL << 20) )
63 static unsigned long reset_value[OP_MAX_COUNTER];
64 int ppro_has_global_ctrl = 0;
65 
ppro_fill_in_addresses(struct op_msrs * const msrs)66 static void ppro_fill_in_addresses(struct op_msrs * const msrs)
67 {
68 	int i;
69 
70 	for (i = 0; i < num_counters; i++)
71 		msrs->counters[i].addr = MSR_P6_PERFCTR(i);
72 	for (i = 0; i < num_counters; i++)
73 		msrs->controls[i].addr = MSR_P6_EVNTSEL(i);
74 }
75 
76 
ppro_setup_ctrs(struct op_msrs const * const msrs)77 static void ppro_setup_ctrs(struct op_msrs const * const msrs)
78 {
79 	uint64_t msr_content;
80 	int i;
81 
82 	if (cpu_has_arch_perfmon) {
83 		union cpuid10_eax eax;
84 		eax.full = cpuid_eax(0xa);
85 
86 		/*
87 		 * For Core2 (family 6, model 15), don't reset the
88 		 * counter width:
89 		 */
90 		if (!(eax.split.version_id == 0 &&
91 			current_cpu_data.x86 == 6 &&
92 				current_cpu_data.x86_model == 15)) {
93 
94 			if (counter_width < eax.split.bit_width)
95 				counter_width = eax.split.bit_width;
96 		}
97 	}
98 
99 	/* clear all counters */
100 	for (i = 0 ; i < num_counters; ++i) {
101 		CTRL_READ(msr_content, msrs, i);
102 		CTRL_CLEAR(msr_content);
103 		CTRL_WRITE(msr_content, msrs, i);
104 	}
105 
106 	/* avoid a false detection of ctr overflows in NMI handler */
107 	for (i = 0; i < num_counters; ++i)
108 		wrmsrl(msrs->counters[i].addr, ~0x0ULL);
109 
110 	/* enable active counters */
111 	for (i = 0; i < num_counters; ++i) {
112 		if (counter_config[i].enabled) {
113 			reset_value[i] = counter_config[i].count;
114 
115 			wrmsrl(msrs->counters[i].addr, -reset_value[i]);
116 
117 			CTRL_READ(msr_content, msrs, i);
118 			CTRL_CLEAR(msr_content);
119 			CTRL_SET_ENABLE(msr_content);
120 			CTRL_SET_USR(msr_content, counter_config[i].user);
121 			CTRL_SET_KERN(msr_content, counter_config[i].kernel);
122 			CTRL_SET_UM(msr_content, counter_config[i].unit_mask);
123 			CTRL_SET_EVENT(msr_content, counter_config[i].event);
124 			CTRL_WRITE(msr_content, msrs, i);
125 		} else {
126 			reset_value[i] = 0;
127 		}
128 	}
129 }
130 
ppro_check_ctrs(unsigned int const cpu,struct op_msrs const * const msrs,struct cpu_user_regs const * const regs)131 static int ppro_check_ctrs(unsigned int const cpu,
132                            struct op_msrs const * const msrs,
133                            struct cpu_user_regs const * const regs)
134 {
135 	u64 val;
136 	int i;
137 	int ovf = 0;
138 	unsigned long eip = regs->rip;
139 	int mode = xenoprofile_get_mode(current, regs);
140 	struct arch_msr_pair *msrs_content = vcpu_vpmu(current)->context;
141 
142 	for (i = 0 ; i < num_counters; ++i) {
143 		if (!reset_value[i])
144 			continue;
145 		rdmsrl(msrs->counters[i].addr, val);
146 		if (CTR_OVERFLOWED(val)) {
147 			xenoprof_log_event(current, regs, eip, mode, i);
148 			wrmsrl(msrs->counters[i].addr, -reset_value[i]);
149 			if ( is_passive(current->domain) && (mode != 2) &&
150 				vpmu_is_set(vcpu_vpmu(current),
151                                             VPMU_PASSIVE_DOMAIN_ALLOCATED) )
152 			{
153 				if ( IS_ACTIVE(msrs_content[i].control) )
154 				{
155 					msrs_content[i].counter = val;
156 					if ( IS_ENABLE(msrs_content[i].control) )
157 						ovf = 2;
158 				}
159 			}
160 			if ( !ovf )
161 				ovf = 1;
162 		}
163 	}
164 
165 	/* Only P6 based Pentium M need to re-unmask the apic vector but it
166 	 * doesn't hurt other P6 variant */
167 	apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED);
168 
169 	return ovf;
170 }
171 
172 
ppro_start(struct op_msrs const * const msrs)173 static void ppro_start(struct op_msrs const * const msrs)
174 {
175 	uint64_t msr_content;
176 	int i;
177 
178 	for (i = 0; i < num_counters; ++i) {
179 		if (reset_value[i]) {
180 			CTRL_READ(msr_content, msrs, i);
181 			CTRL_SET_ACTIVE(msr_content);
182 			CTRL_WRITE(msr_content, msrs, i);
183 		}
184 	}
185     /* Global Control MSR is enabled by default when system power on.
186      * However, this may not hold true when xenoprof starts to run.
187      */
188     if ( ppro_has_global_ctrl )
189         wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, (1ULL<<num_counters) - 1);
190 }
191 
192 
ppro_stop(struct op_msrs const * const msrs)193 static void ppro_stop(struct op_msrs const * const msrs)
194 {
195 	uint64_t msr_content;
196 	int i;
197 
198 	for (i = 0; i < num_counters; ++i) {
199 		if (!reset_value[i])
200 			continue;
201 		CTRL_READ(msr_content, msrs, i);
202 		CTRL_SET_INACTIVE(msr_content);
203 		CTRL_WRITE(msr_content, msrs, i);
204 	}
205     if ( ppro_has_global_ctrl )
206         wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0x0ULL);
207 }
208 
ppro_is_arch_pmu_msr(u64 msr_index,int * type,int * index)209 static int ppro_is_arch_pmu_msr(u64 msr_index, int *type, int *index)
210 {
211 	if ( (msr_index >= MSR_IA32_PERFCTR0) &&
212             (msr_index < (MSR_IA32_PERFCTR0 + num_counters)) )
213 	{
214 		*type = MSR_TYPE_ARCH_COUNTER;
215 		*index = msr_index - MSR_IA32_PERFCTR0;
216 		return 1;
217         }
218         if ( (msr_index >= MSR_P6_EVNTSEL(0)) &&
219             (msr_index < (MSR_P6_EVNTSEL(num_counters))) )
220         {
221 		*type = MSR_TYPE_ARCH_CTRL;
222 		*index = msr_index - MSR_P6_EVNTSEL(0);
223 		return 1;
224         }
225 
226         return 0;
227 }
228 
ppro_allocate_msr(struct vcpu * v)229 static int ppro_allocate_msr(struct vcpu *v)
230 {
231 	struct vpmu_struct *vpmu = vcpu_vpmu(v);
232 	struct arch_msr_pair *msr_content;
233 
234 	msr_content = xzalloc_array(struct arch_msr_pair, num_counters);
235 	if ( !msr_content )
236 		goto out;
237 	vpmu->context = (void *)msr_content;
238 	vpmu_clear(vpmu);
239 	vpmu_set(vpmu, VPMU_PASSIVE_DOMAIN_ALLOCATED);
240 	return 1;
241 out:
242 	printk(XENLOG_G_WARNING "Insufficient memory for oprofile,"
243 	       " oprofile is unavailable on dom%d vcpu%d\n",
244 	       v->vcpu_id, v->domain->domain_id);
245 	return 0;
246 }
247 
ppro_free_msr(struct vcpu * v)248 static void ppro_free_msr(struct vcpu *v)
249 {
250 	struct vpmu_struct *vpmu = vcpu_vpmu(v);
251 
252 	if ( !vpmu_is_set(vpmu, VPMU_PASSIVE_DOMAIN_ALLOCATED) )
253 		return;
254 	xfree(vpmu->context);
255 	vpmu_reset(vpmu, VPMU_PASSIVE_DOMAIN_ALLOCATED);
256 }
257 
ppro_load_msr(struct vcpu * v,int type,int index,u64 * msr_content)258 static void ppro_load_msr(struct vcpu *v, int type, int index, u64 *msr_content)
259 {
260 	struct arch_msr_pair *msrs = vcpu_vpmu(v)->context;
261 	switch ( type )
262 	{
263 	case MSR_TYPE_ARCH_COUNTER:
264 		*msr_content = msrs[index].counter;
265 		break;
266 	case MSR_TYPE_ARCH_CTRL:
267 		*msr_content = msrs[index].control;
268 		break;
269 	}
270 }
271 
ppro_save_msr(struct vcpu * v,int type,int index,u64 msr_content)272 static void ppro_save_msr(struct vcpu *v, int type, int index, u64 msr_content)
273 {
274 	struct arch_msr_pair *msrs = vcpu_vpmu(v)->context;
275 
276 	switch ( type )
277 	{
278 	case MSR_TYPE_ARCH_COUNTER:
279 		msrs[index].counter = msr_content;
280 		break;
281 	case MSR_TYPE_ARCH_CTRL:
282 		msrs[index].control = msr_content;
283 		break;
284 	}
285 }
286 
287 /*
288  * Architectural performance monitoring.
289  *
290  * Newer Intel CPUs (Core1+) have support for architectural
291  * events described in CPUID 0xA. See the IA32 SDM Vol3b.18 for details.
292  * The advantage of this is that it can be done without knowing about
293  * the specific CPU.
294  */
arch_perfmon_setup_counters(void)295 void arch_perfmon_setup_counters(void)
296 {
297 	union cpuid10_eax eax;
298 
299 	eax.full = cpuid_eax(0xa);
300 
301 	/* Workaround for BIOS bugs in 6/15. Taken from perfmon2 */
302 	if (eax.split.version_id == 0 && current_cpu_data.x86 == 6 &&
303 	    current_cpu_data.x86_model == 15) {
304 		eax.split.version_id = 2;
305 		eax.split.num_counters = 2;
306 		eax.split.bit_width = 40;
307 	}
308 
309 	num_counters = min_t(u8, eax.split.num_counters, OP_MAX_COUNTER);
310 
311 	op_arch_perfmon_spec.num_counters = num_counters;
312 	op_arch_perfmon_spec.num_controls = num_counters;
313 	op_ppro_spec.num_counters = num_counters;
314 	op_ppro_spec.num_controls = num_counters;
315 }
316 
317 struct op_x86_model_spec __read_mostly op_ppro_spec = {
318 	.num_counters = 2,
319 	.num_controls = 2,
320 	.fill_in_addresses = &ppro_fill_in_addresses,
321 	.setup_ctrs = &ppro_setup_ctrs,
322 	.check_ctrs = &ppro_check_ctrs,
323 	.start = &ppro_start,
324 	.stop = &ppro_stop,
325 	.is_arch_pmu_msr = &ppro_is_arch_pmu_msr,
326 	.allocated_msr = &ppro_allocate_msr,
327 	.free_msr = &ppro_free_msr,
328 	.load_msr = &ppro_load_msr,
329 	.save_msr = &ppro_save_msr
330 };
331 
332 struct op_x86_model_spec __read_mostly op_arch_perfmon_spec = {
333 	/* num_counters/num_controls filled in at runtime */
334 	.fill_in_addresses = &ppro_fill_in_addresses,
335 	.setup_ctrs = &ppro_setup_ctrs,
336 	.check_ctrs = &ppro_check_ctrs,
337 	.start = &ppro_start,
338 	.stop = &ppro_stop,
339 	.is_arch_pmu_msr = &ppro_is_arch_pmu_msr,
340 	.allocated_msr = &ppro_allocate_msr,
341 	.free_msr = &ppro_free_msr,
342 	.load_msr = &ppro_load_msr,
343 	.save_msr = &ppro_save_msr
344 };
345