[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [RFC PATCH v1 05/10] pmu.h: introduce a stacktrace area


  • To: Edwin Török <edwin.torok@xxxxxxxxx>
  • From: Jan Beulich <jbeulich@xxxxxxxx>
  • Date: Thu, 28 Aug 2025 14:04:19 +0200
  • Autocrypt: addr=jbeulich@xxxxxxxx; keydata= xsDiBFk3nEQRBADAEaSw6zC/EJkiwGPXbWtPxl2xCdSoeepS07jW8UgcHNurfHvUzogEq5xk hu507c3BarVjyWCJOylMNR98Yd8VqD9UfmX0Hb8/BrA+Hl6/DB/eqGptrf4BSRwcZQM32aZK 7Pj2XbGWIUrZrd70x1eAP9QE3P79Y2oLrsCgbZJfEwCgvz9JjGmQqQkRiTVzlZVCJYcyGGsD /0tbFCzD2h20ahe8rC1gbb3K3qk+LpBtvjBu1RY9drYk0NymiGbJWZgab6t1jM7sk2vuf0Py O9Hf9XBmK0uE9IgMaiCpc32XV9oASz6UJebwkX+zF2jG5I1BfnO9g7KlotcA/v5ClMjgo6Gl MDY4HxoSRu3i1cqqSDtVlt+AOVBJBACrZcnHAUSuCXBPy0jOlBhxPqRWv6ND4c9PH1xjQ3NP nxJuMBS8rnNg22uyfAgmBKNLpLgAGVRMZGaGoJObGf72s6TeIqKJo/LtggAS9qAUiuKVnygo 3wjfkS9A3DRO+SpU7JqWdsveeIQyeyEJ/8PTowmSQLakF+3fote9ybzd880fSmFuIEJldWxp Y2ggPGpiZXVsaWNoQHN1c2UuY29tPsJgBBMRAgAgBQJZN5xEAhsDBgsJCAcDAgQVAggDBBYC AwECHgECF4AACgkQoDSui/t3IH4J+wCfQ5jHdEjCRHj23O/5ttg9r9OIruwAn3103WUITZee e7Sbg12UgcQ5lv7SzsFNBFk3nEQQCACCuTjCjFOUdi5Nm244F+78kLghRcin/awv+IrTcIWF hUpSs1Y91iQQ7KItirz5uwCPlwejSJDQJLIS+QtJHaXDXeV6NI0Uef1hP20+y8qydDiVkv6l IreXjTb7DvksRgJNvCkWtYnlS3mYvQ9NzS9PhyALWbXnH6sIJd2O9lKS1Mrfq+y0IXCP10eS FFGg+Av3IQeFatkJAyju0PPthyTqxSI4lZYuJVPknzgaeuJv/2NccrPvmeDg6Coe7ZIeQ8Yj t0ARxu2xytAkkLCel1Lz1WLmwLstV30g80nkgZf/wr+/BXJW/oIvRlonUkxv+IbBM3dX2OV8 AmRv1ySWPTP7AAMFB/9PQK/VtlNUJvg8GXj9ootzrteGfVZVVT4XBJkfwBcpC/XcPzldjv+3 HYudvpdNK3lLujXeA5fLOH+Z/G9WBc5pFVSMocI71I8bT8lIAzreg0WvkWg5V2WZsUMlnDL9 mpwIGFhlbM3gfDMs7MPMu8YQRFVdUvtSpaAs8OFfGQ0ia3LGZcjA6Ik2+xcqscEJzNH+qh8V m5jjp28yZgaqTaRbg3M/+MTbMpicpZuqF4rnB0AQD12/3BNWDR6bmh+EkYSMcEIpQmBM51qM EKYTQGybRCjpnKHGOxG0rfFY1085mBDZCH5Kx0cl0HVJuQKC+dV2ZY5AqjcKwAxpE75MLFkr wkkEGBECAAkFAlk3nEQCGwwACgkQoDSui/t3IH7nnwCfcJWUDUFKdCsBH/E5d+0ZnMQi+G0A nAuWpQkjM1ASeQwSHEeAWPgskBQL
  • Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>, Anthony PERARD <anthony.perard@xxxxxxxxxx>, Michal Orzel <michal.orzel@xxxxxxx>, Julien Grall <julien@xxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>, andriy.sultanov@xxxxxxxxxx, boris.ostrovsky@xxxxxxxxxx, xen-devel@xxxxxxxxxxxxxxxxxxxx
  • Delivery-date: Thu, 28 Aug 2025 12:04:30 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On 25.07.2025 17:06, Edwin Török wrote:
> The guest always allocates a full page that is mapped for 'struct
> xen_pmu_data' (there is no smaller mapping granularity).
> 
> The existing struct contains a flexible array member that is used to
> store architectural performance counters on Intel (their number is
> dynamically determined from CPUID).
> 
> AFAICT their number is currently limited to 32 due to the bitmap in the
> CPUID only having 32 bits defined for this, although the cpuid has 8
> bits reserved to specify the number of these counters, so this may grow.
> 
> For backwards compatibility and to leave as much room for future growth
> in these counters as possible: the newly introduced hypervisor
> stacktrace area will be stored at the end of the page.
> 
> Conceptually this would've been:
> ```
> struct xen_pmu_data_v2 {
>     union {
>         struct xen_pmu_data v1;
>         uint8_t pad[PAGE_SIZE - sizeof(struct xen_pmu_hv_stacktrace)];
>     };
>     struct xen_pmu_hv_stacktrace pmu_stack;
> };
> ```
> 
> But that is not valid C due to the flexible array member in v1.

And I fear it's not a good interface anyway. What's wrong with the caller
dedicating another page to holding the stack trace related data?

> There is code duplication in 'struct xen_pmu_arch_guest',
> but xlat.h checker fails if I try to reuse that in the definition of
> xen_pmu_arch_t.

What exactly is this referring to?

> --- a/xen/include/public/arch-x86/pmu.h
> +++ b/xen/include/public/arch-x86/pmu.h
> @@ -74,6 +74,23 @@ DEFINE_XEN_GUEST_HANDLE(xen_pmu_regs_t);
>  #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 the state of the guest at
> + * the time of a PMU interrupt.
> + */
> +struct xen_pmu_arch_guest {
> +    union {
> +        /*
> +         * Processor's registers at the time of interrupt.
> +         * WO for hypervisor, RO for guests.
> +         */
> +        xen_pmu_regs_t regs;

How's this related to stack traces?

> @@ -129,67 +146,86 @@ struct xen_pmu_arch {
>  typedef struct xen_pmu_arch xen_pmu_arch_t;
>  DEFINE_XEN_GUEST_HANDLE(xen_pmu_arch_t);
>  
> +

Stray double blank lines.

>  /* 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]  ┆   ╞═════╡  │
> -* │      │                        │                  ┆   │     │  │
> -* │      │                        │                  ▽   │     │  │
> -* │      │                        ╘══════════════════════╛     │  │
> -* │      ╘═════════════════════════════════════════════════════╡  │
> -* ╞════════════════════════════════════════════════════════════╡  │
> -* │████████████████████████████████████████████████████████████│  │
> -* ┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆  ┆
> -* ┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆┆  ┆
> -* │████████████████████████████████████████████████████████████│  │ PAGE_SIZE
> -* ╘════════════════════════════════════════════════════════════╛ ◁╯
> + *                ╭─────────────────────╮
> + *                │ 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 /* __XEN_PUBLIC_ARCH_X86_PMU_H__ */
> @@ -202,4 +238,3 @@ DEFINE_XEN_GUEST_HANDLE(xen_pmu_arch_t);
>   * indent-tabs-mode: nil
>   * End:
>   */
> -

Stray change?

> @@ -120,6 +120,40 @@ struct xen_pmu_data {
>      xen_pmu_arch_t 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;

How's this related to stack traces? And how would it help associating back
what vCPU the data belongs to?

> +    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.
> +    * */

Nit: Indentation.

Jan



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.