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