[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [RFC LINUX PATCH v1 2/3] xen/{interface,xenpmu}.h: update with VPMU 0.2 from Xen
Signed-off-by: Edwin Török <edwin.torok@xxxxxxxxx> --- arch/x86/include/asm/xen/interface.h | 100 +++++++++++++++++++++++++++ include/xen/interface/xenpmu.h | 56 +++++++++++++-- 2 files changed, 152 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/xen/interface.h b/arch/x86/include/asm/xen/interface.h index baca0b00ef76..f3667831573f 100644 --- a/arch/x86/include/asm/xen/interface.h +++ b/arch/x86/include/asm/xen/interface.h @@ -320,6 +320,25 @@ struct xen_pmu_regs { #define PMU_SAMPLE_REAL (1<<2) /* Sample is from realmode */ #define PMU_SAMPLE_PV (1<<3) /* Sample from a PV guest */ +/* + * Architecture-specific information describing state of the guest at + * the time of PMU interrupt. + * Even if the interrupt arrived while inside Xen, this will always contain + * the guest's state. + */ +struct xen_pmu_arch_guest { + union { + /* + * Processor's registers at the time of interrupt. + * WO for hypervisor, RO for guests. + */ + struct xen_pmu_regs regs; + /* Padding for adding new registers to xen_pmu_regs in the future */ +#define XENPMU_REGS_PAD_SZ 64 + uint8_t pad[XENPMU_REGS_PAD_SZ]; + } r; +}; + /* * Architecture-specific information describing state of the processor at * the time of PMU interrupt. @@ -376,6 +395,87 @@ struct xen_pmu_arch { } c; }; +/* Memory layout: + * ╭─────────────────────╮ + * │ struct xen_pmu_data │ + * ╒══════════════╧═════════════════════╧═══════════════════════╕ ◁│ + * │ vcpu_id │ │ + * ├────────────────────────────────────────────────────────────┤ │ + * │ pcpu_id │ │ + * ├────────────────────────────────────────────────────────────┤ │ + * │ domain_id │ │ + * ├────────────────────────────────────────────────────────────┤ │ + * │██pad███████████████████████████████████████████████████████│ │ + * ╞════╤═╤═══╤══════════════════╤══════════════════════════════╡ │ + * │ pmu│ │ r │ regs │██pad█████████████████████████│ │ + * ├────╯ ├───╯ (xen or guest) │██████████████████████████████│ │ + * │ ╞══════════════════════╧══════════════════════════════╡ │ + * │ │ pmu_flags │ │ + * │ ╞═══╤════════════════════╤════════════════════════════╡ │ + * │ │ l │ lapic_lvtpc │████████████████████████████│ │ + * │ ├───╯ ███████████████████│██pad███████████████████████│ │ + * │ │ ███████████████████│████████████████████████████│ │ + * │ ╞═══╤═╤═══════╤═════╤════╪════╤═══════╤═══════════════╡ │ + * │ │ c │ │ │ amd │ │ │ intel │ │█████│ │ + * │ ├───┘ │ ╰─────╯ │ ╰───────╯ │█████│ │ + * │ │ │ counter │ fixed_counters │█████│ │ + * │ │ ├──────────────────┼──────────────────────┤█████│ │ + * │ │ │ ctrls │ arch_counters │█████│ │ + * │ │ ╞═════╤════════╤═══├──────────────────────┤█████│ │ + * │ │ │ │ regs[] │ ┆│ global_ctrl │█████│ │ + * │ │ │ └────────╯ ┆├──────────────────────┤█████│ │ + * │ │ │struct ┆│ global_ovf_ctrl │█████│ │ + * │ │ │xen_pmu_cntr_pair┆├──────────────────────┤█████│ │ + * │ │ │[counters] ┆│ global_status │█████│ │ + * │ │ │ ┆├──────────────────────┤█████│ │ + * │ │ │ ┆│ fixed_ctrl │█████│ │ + * │ │ │ ┆├──────────────────────┤█████│ │ + * │ │ │ ┆│ ds_area │█████│ │ + * │ │ │ ┆├──────────────────────┤█████│ │ + * │ │ │ ┆│ pebs_enable │█pad█│ │ + * │ │ │ ┆├──────────────────────┤█████│ │ + * │ │ │ ▽│ debugctl │█████│ │ + * │ │ │██████████████████╞═══════╤════════╤═════╡█████│ │ + * │ │ │██████████████████│ │ regs[] │ ┆[0]│█████│ │ + * │ │ │██████████████████│ └────────╯ ┆ │█████│ │ + * │ │ │██████████████████│ uint64_t ┆ │█████│ │ + * │ │ │██████████████████│ [fixed_counters] ┆ │█████│ │ + * │ │ │██████████████████│ ┆ │█████│ │ + * │ │ │██████████████████│ ┆ │█████│ │ + * │ │ │██████████████████│ ─────────────────┆ │█████│ │ + * │ │ │██████████████████│ struct ┆ │█████│ │ + * │ │ │██████████████████│ xen_pmu_cntr_pair┆ │█████│ │ + * │ │ ╘══════════════════╡ [arch_counters] ┆ ╞═════╡ │ + * │ │ │ ┆ │ │ │ + * │ │ │ ▽ │ │ │ + * │ │ ╘══════════════════════╛ │ │ + * │ ╘═════════════════════════════════════════════════════╡ │ + * ╞════════════════════════════════════════════════════════════╡ │ + * │████████████████████████████████████████████████████████████│ │ + * ┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆ ┆ + * ┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆ ┆ + * │████████████████████████████████████████████████████████████│ │ + * │████████████████████████████████████████████████████████████│ │ + * │██████████╭──────────────────────────────╮██████████████████│ │ + * │██████████│ struct xen_pmu_hv_stacktrace │██████████████████│ │ + * ╞══════════╧══════════════════════════════╧══════════════════╡ │ + * │ △ [stacktrace_nr-1] │ │ + * │ ┆ │ │ + * │ stacktrace[stacktrace_nr] ┆ [0] │ │ + * ├────────────────────────────────────────────────────────────┤ │ + * │ stacktrace_nr │ │ + * ├────────────────────────────────────────────────────────────┤ │ + * │ guest_domain_id │ │ + * ├────────────────────────────────────────────────────────────┤ │ + * │██pad███████████████████████████████████████████████████████│ │ + * ╞═══════╤═╤═══╤══════════════════╤═══════════════════════════╡ │ + * │ guest │ │ r │ regs │██pad██████████████████████│ │ + * ├───────╯ ├───╯ (xen or guest) │███████████████████████████│ │ + * │ ╞══════════════════════╧═══════════════════════════╡ │ + * │ │██pad2████████████████████████████████████████████│ │ PAGE_SIZE + * ╘═════════╧══════════════════════════════════════════════════╛ ◁╯ + */ + #endif /* !__ASSEMBLY__ */ /* diff --git a/include/xen/interface/xenpmu.h b/include/xen/interface/xenpmu.h index e2ee73d91bd6..c4dfa8e349f7 100644 --- a/include/xen/interface/xenpmu.h +++ b/include/xen/interface/xenpmu.h @@ -5,7 +5,7 @@ #include "xen.h" #define XENPMU_VER_MAJ 0 -#define XENPMU_VER_MIN 1 +#define XENPMU_VER_MIN 2 /* * ` enum neg_errnoval @@ -22,8 +22,7 @@ #define XENPMU_init 4 #define XENPMU_finish 5 #define XENPMU_lvtpc_set 6 -#define XENPMU_flush 7 - +#define XENPMU_flush 7 /* Write cached MSR values to HW */ /* ` } */ /* Parameters structure for HYPERVISOR_xenpmu_op call */ @@ -56,8 +55,20 @@ struct xen_pmu_params { /* * PMU features: * - XENPMU_FEATURE_INTEL_BTS: Intel BTS support (ignored on AMD) + * - XENPMU_FEATURE_IPC_ONLY: Restrict PMCs to the most minimum set possible. + * Instructions, cycles, and ref cycles. Can be + * used to calculate instructions-per-cycle (IPC) + * (ignored on AMD). + * - XENPMU_FEATURE_ARCH_ONLY: Restrict PMCs to the Intel Pre-Defined + * Architectural Performance Events exposed by + * cpuid and listed in the Intel developer's manual + * (ignored on AMD). + * - XENPMU_FEATURE_HV_STACKTRACE: Hypervisor stacktraces (when compiled with frame pointers) */ -#define XENPMU_FEATURE_INTEL_BTS 1 +#define XENPMU_FEATURE_INTEL_BTS (1<<0) +#define XENPMU_FEATURE_IPC_ONLY (1<<1) +#define XENPMU_FEATURE_ARCH_ONLY (1<<2) +#define XENPMU_FEATURE_HV_STACKTRACE (1<<3) /* * Shared PMU data between hypervisor and PV(H) domains. @@ -67,6 +78,9 @@ struct xen_pmu_params { * Architecture-independent fields of xen_pmu_data are WO for the hypervisor * and RO for the guest but some fields in xen_pmu_arch can be writable * by both the hypervisor and the guest (see arch-$arch/pmu.h). + * + * PAGE_SIZE bytes of memory are allocated. + * This struct cannot be larger than PAGE_SIZE. */ struct xen_pmu_data { /* Interrupted VCPU */ @@ -92,4 +106,38 @@ struct xen_pmu_data { struct xen_pmu_arch pmu; }; +/* stacktrace entry populated from the end, + * so stacktrace_nr == 1, means that stacktrace[PMU_MAX_STACKTRCE-1] is valid. + * This is done, so that PMU_MAX_STACKTRACE can be changed in the future, without breaking the ABI. + * The struct itself (and thus the stacktrace_nr field) will always be placed at the end of a page. + * + * See arch-x86/pmu.h for an example memory layout on x86. + * + */ +#define PMU_MAX_STACKTRACE 127 + +/* WO for hypervisor, RO for guest */ +struct xen_pmu_hv_stacktrace { + uint64_t stacktrace[PMU_MAX_STACKTRACE]; + uint64_t stacktrace_nr; + + /* Like xen_pmu_data.domain_id, but instead of DOMID_XEN always contains the + * domain that was interrupted (DOMID_SELF if it matches the sampling + * domain). + */ + domid_t guest_domain_id; + uint8_t pad[6]; + + /* When xen_pmu_data.domain_id == DOMID_XEN, this will contain + * the registers of the guest that was interrupted. + * This is useful for Dom0 kernel stacktraces, even if the interrupt + * arrives while in Xen. + */ + struct xen_pmu_arch_guest guest; +#define XEN_PMU_STACKTRACE_PAD 56 + uint8_t pad2[XEN_PMU_STACKTRACE_PAD]; +}; + +#define MAX_XEN_PMU_DATA_SIZE (PAGE_SIZE - sizeof(struct xen_pmu_hv_stacktrace)) + #endif /* __XEN_PUBLIC_XENPMU_H__ */ -- 2.47.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |