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