xref: /freebsd/sys/contrib/xen/arch-x86/pmu.h (revision 3a9fd8242b35884921dfc4e886f284a75870a536)
1*3a9fd824SRoger Pau Monné /*
2*3a9fd824SRoger Pau Monné  * Permission is hereby granted, free of charge, to any person obtaining a copy
3*3a9fd824SRoger Pau Monné  * of this software and associated documentation files (the "Software"), to
4*3a9fd824SRoger Pau Monné  * deal in the Software without restriction, including without limitation the
5*3a9fd824SRoger Pau Monné  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
6*3a9fd824SRoger Pau Monné  * sell copies of the Software, and to permit persons to whom the Software is
7*3a9fd824SRoger Pau Monné  * furnished to do so, subject to the following conditions:
8*3a9fd824SRoger Pau Monné  *
9*3a9fd824SRoger Pau Monné  * The above copyright notice and this permission notice shall be included in
10*3a9fd824SRoger Pau Monné  * all copies or substantial portions of the Software.
11*3a9fd824SRoger Pau Monné  *
12*3a9fd824SRoger Pau Monné  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13*3a9fd824SRoger Pau Monné  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14*3a9fd824SRoger Pau Monné  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15*3a9fd824SRoger Pau Monné  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16*3a9fd824SRoger Pau Monné  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
17*3a9fd824SRoger Pau Monné  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
18*3a9fd824SRoger Pau Monné  * DEALINGS IN THE SOFTWARE.
19*3a9fd824SRoger Pau Monné  *
20*3a9fd824SRoger Pau Monné  * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
21*3a9fd824SRoger Pau Monné  */
22*3a9fd824SRoger Pau Monné 
23*3a9fd824SRoger Pau Monné #ifndef __XEN_PUBLIC_ARCH_X86_PMU_H__
24*3a9fd824SRoger Pau Monné #define __XEN_PUBLIC_ARCH_X86_PMU_H__
25*3a9fd824SRoger Pau Monné 
26*3a9fd824SRoger Pau Monné /* x86-specific PMU definitions */
27*3a9fd824SRoger Pau Monné 
28*3a9fd824SRoger Pau Monné /* AMD PMU registers and structures */
29*3a9fd824SRoger Pau Monné struct xen_pmu_amd_ctxt {
30*3a9fd824SRoger Pau Monné     /*
31*3a9fd824SRoger Pau Monné      * Offsets to counter and control MSRs (relative to xen_pmu_arch.c.amd).
32*3a9fd824SRoger Pau Monné      * For PV(H) guests these fields are RO.
33*3a9fd824SRoger Pau Monné      */
34*3a9fd824SRoger Pau Monné     uint32_t counters;
35*3a9fd824SRoger Pau Monné     uint32_t ctrls;
36*3a9fd824SRoger Pau Monné 
37*3a9fd824SRoger Pau Monné     /* Counter MSRs */
38*3a9fd824SRoger Pau Monné     uint64_t regs[XEN_FLEX_ARRAY_DIM];
39*3a9fd824SRoger Pau Monné };
40*3a9fd824SRoger Pau Monné typedef struct xen_pmu_amd_ctxt xen_pmu_amd_ctxt_t;
41*3a9fd824SRoger Pau Monné DEFINE_XEN_GUEST_HANDLE(xen_pmu_amd_ctxt_t);
42*3a9fd824SRoger Pau Monné 
43*3a9fd824SRoger Pau Monné /* Intel PMU registers and structures */
44*3a9fd824SRoger Pau Monné struct xen_pmu_cntr_pair {
45*3a9fd824SRoger Pau Monné     uint64_t counter;
46*3a9fd824SRoger Pau Monné     uint64_t control;
47*3a9fd824SRoger Pau Monné };
48*3a9fd824SRoger Pau Monné typedef struct xen_pmu_cntr_pair xen_pmu_cntr_pair_t;
49*3a9fd824SRoger Pau Monné DEFINE_XEN_GUEST_HANDLE(xen_pmu_cntr_pair_t);
50*3a9fd824SRoger Pau Monné 
51*3a9fd824SRoger Pau Monné struct xen_pmu_intel_ctxt {
52*3a9fd824SRoger Pau Monné    /*
53*3a9fd824SRoger Pau Monné     * Offsets to fixed and architectural counter MSRs (relative to
54*3a9fd824SRoger Pau Monné     * xen_pmu_arch.c.intel).
55*3a9fd824SRoger Pau Monné     * For PV(H) guests these fields are RO.
56*3a9fd824SRoger Pau Monné     */
57*3a9fd824SRoger Pau Monné     uint32_t fixed_counters;
58*3a9fd824SRoger Pau Monné     uint32_t arch_counters;
59*3a9fd824SRoger Pau Monné 
60*3a9fd824SRoger Pau Monné     /* PMU registers */
61*3a9fd824SRoger Pau Monné     uint64_t global_ctrl;
62*3a9fd824SRoger Pau Monné     uint64_t global_ovf_ctrl;
63*3a9fd824SRoger Pau Monné     uint64_t global_status;
64*3a9fd824SRoger Pau Monné     uint64_t fixed_ctrl;
65*3a9fd824SRoger Pau Monné     uint64_t ds_area;
66*3a9fd824SRoger Pau Monné     uint64_t pebs_enable;
67*3a9fd824SRoger Pau Monné     uint64_t debugctl;
68*3a9fd824SRoger Pau Monné 
69*3a9fd824SRoger Pau Monné     /* Fixed and architectural counter MSRs */
70*3a9fd824SRoger Pau Monné     uint64_t regs[XEN_FLEX_ARRAY_DIM];
71*3a9fd824SRoger Pau Monné };
72*3a9fd824SRoger Pau Monné typedef struct xen_pmu_intel_ctxt xen_pmu_intel_ctxt_t;
73*3a9fd824SRoger Pau Monné DEFINE_XEN_GUEST_HANDLE(xen_pmu_intel_ctxt_t);
74*3a9fd824SRoger Pau Monné 
75*3a9fd824SRoger Pau Monné /* Sampled domain's registers */
76*3a9fd824SRoger Pau Monné struct xen_pmu_regs {
77*3a9fd824SRoger Pau Monné     uint64_t ip;
78*3a9fd824SRoger Pau Monné     uint64_t sp;
79*3a9fd824SRoger Pau Monné     uint64_t flags;
80*3a9fd824SRoger Pau Monné     uint16_t cs;
81*3a9fd824SRoger Pau Monné     uint16_t ss;
82*3a9fd824SRoger Pau Monné     uint8_t cpl;
83*3a9fd824SRoger Pau Monné     uint8_t pad[3];
84*3a9fd824SRoger Pau Monné };
85*3a9fd824SRoger Pau Monné typedef struct xen_pmu_regs xen_pmu_regs_t;
86*3a9fd824SRoger Pau Monné DEFINE_XEN_GUEST_HANDLE(xen_pmu_regs_t);
87*3a9fd824SRoger Pau Monné 
88*3a9fd824SRoger Pau Monné /* PMU flags */
89*3a9fd824SRoger Pau Monné #define PMU_CACHED         (1<<0) /* PMU MSRs are cached in the context */
90*3a9fd824SRoger Pau Monné #define PMU_SAMPLE_USER    (1<<1) /* Sample is from user or kernel mode */
91*3a9fd824SRoger Pau Monné #define PMU_SAMPLE_REAL    (1<<2) /* Sample is from realmode */
92*3a9fd824SRoger Pau Monné #define PMU_SAMPLE_PV      (1<<3) /* Sample from a PV guest */
93*3a9fd824SRoger Pau Monné 
94*3a9fd824SRoger Pau Monné /*
95*3a9fd824SRoger Pau Monné  * Architecture-specific information describing state of the processor at
96*3a9fd824SRoger Pau Monné  * the time of PMU interrupt.
97*3a9fd824SRoger Pau Monné  * Fields of this structure marked as RW for guest should only be written by
98*3a9fd824SRoger Pau Monné  * the guest when PMU_CACHED bit in pmu_flags is set (which is done by the
99*3a9fd824SRoger Pau Monné  * hypervisor during PMU interrupt). Hypervisor will read updated data in
100*3a9fd824SRoger Pau Monné  * XENPMU_flush hypercall and clear PMU_CACHED bit.
101*3a9fd824SRoger Pau Monné  */
102*3a9fd824SRoger Pau Monné struct xen_pmu_arch {
103*3a9fd824SRoger Pau Monné     union {
104*3a9fd824SRoger Pau Monné         /*
105*3a9fd824SRoger Pau Monné          * Processor's registers at the time of interrupt.
106*3a9fd824SRoger Pau Monné          * WO for hypervisor, RO for guests.
107*3a9fd824SRoger Pau Monné          */
108*3a9fd824SRoger Pau Monné         xen_pmu_regs_t regs;
109*3a9fd824SRoger Pau Monné         /* Padding for adding new registers to xen_pmu_regs in the future */
110*3a9fd824SRoger Pau Monné #define XENPMU_REGS_PAD_SZ  64
111*3a9fd824SRoger Pau Monné         uint8_t pad[XENPMU_REGS_PAD_SZ];
112*3a9fd824SRoger Pau Monné     } r;
113*3a9fd824SRoger Pau Monné 
114*3a9fd824SRoger Pau Monné     /* WO for hypervisor, RO for guest */
115*3a9fd824SRoger Pau Monné     uint64_t pmu_flags;
116*3a9fd824SRoger Pau Monné 
117*3a9fd824SRoger Pau Monné     /*
118*3a9fd824SRoger Pau Monné      * APIC LVTPC register.
119*3a9fd824SRoger Pau Monné      * RW for both hypervisor and guest.
120*3a9fd824SRoger Pau Monné      * Only APIC_LVT_MASKED bit is loaded by the hypervisor into hardware
121*3a9fd824SRoger Pau Monné      * during XENPMU_flush or XENPMU_lvtpc_set.
122*3a9fd824SRoger Pau Monné      */
123*3a9fd824SRoger Pau Monné     union {
124*3a9fd824SRoger Pau Monné         uint32_t lapic_lvtpc;
125*3a9fd824SRoger Pau Monné         uint64_t pad;
126*3a9fd824SRoger Pau Monné     } l;
127*3a9fd824SRoger Pau Monné 
128*3a9fd824SRoger Pau Monné     /*
129*3a9fd824SRoger Pau Monné      * Vendor-specific PMU registers.
130*3a9fd824SRoger Pau Monné      * RW for both hypervisor and guest (see exceptions above).
131*3a9fd824SRoger Pau Monné      * Guest's updates to this field are verified and then loaded by the
132*3a9fd824SRoger Pau Monné      * hypervisor into hardware during XENPMU_flush
133*3a9fd824SRoger Pau Monné      */
134*3a9fd824SRoger Pau Monné     union {
135*3a9fd824SRoger Pau Monné         xen_pmu_amd_ctxt_t amd;
136*3a9fd824SRoger Pau Monné         xen_pmu_intel_ctxt_t intel;
137*3a9fd824SRoger Pau Monné 
138*3a9fd824SRoger Pau Monné         /*
139*3a9fd824SRoger Pau Monné          * Padding for contexts (fixed parts only, does not include MSR banks
140*3a9fd824SRoger Pau Monné          * that are specified by offsets)
141*3a9fd824SRoger Pau Monné          */
142*3a9fd824SRoger Pau Monné #define XENPMU_CTXT_PAD_SZ  128
143*3a9fd824SRoger Pau Monné         uint8_t pad[XENPMU_CTXT_PAD_SZ];
144*3a9fd824SRoger Pau Monné     } c;
145*3a9fd824SRoger Pau Monné };
146*3a9fd824SRoger Pau Monné typedef struct xen_pmu_arch xen_pmu_arch_t;
147*3a9fd824SRoger Pau Monné DEFINE_XEN_GUEST_HANDLE(xen_pmu_arch_t);
148*3a9fd824SRoger Pau Monné 
149*3a9fd824SRoger Pau Monné #endif /* __XEN_PUBLIC_ARCH_X86_PMU_H__ */
150*3a9fd824SRoger Pau Monné /*
151*3a9fd824SRoger Pau Monné  * Local variables:
152*3a9fd824SRoger Pau Monné  * mode: C
153*3a9fd824SRoger Pau Monné  * c-file-style: "BSD"
154*3a9fd824SRoger Pau Monné  * c-basic-offset: 4
155*3a9fd824SRoger Pau Monné  * tab-width: 4
156*3a9fd824SRoger Pau Monné  * indent-tabs-mode: nil
157*3a9fd824SRoger Pau Monné  * End:
158*3a9fd824SRoger Pau Monné  */
159*3a9fd824SRoger Pau Monné 
160