Skip to content

Conversation

@opsiff
Copy link
Member

@opsiff opsiff commented Dec 16, 2025

Intel inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/intel-kernel/issues/ICZHEB CVE: NA


Following upstream commits introduced 2 fields (config1 and dyn_constraint) in struct hw_perf_event, which breaks kABI.

ec980e4facef ("perf/x86/intel: Support auto counter reload")
4dfe3232cc04 ("perf/x86: Add dynamic constraint")

To fix this kABI breakage, we introduce struct hw_perf_event_ext, and use one KABI_RESERVE field in struct perf_event as pointer to this struct hw_perf_event_ext. This is viable because hw_perf_event is always embedded in struct perf_event, so we can always access hw_perf_event_ext from perf_event when needed.

We also create a kmem_cache for struct hw_per_event_ext.

Another kABI changes are caused by the following commit:

0e102ce3d413 ("KVM: x86/pmu: Change ambiguous _mask suffix to _rsvd in kvm_pmu")

But the fix is trivial.

Fixes: ec980e4 ("perf/x86/intel: Support auto counter reload")
Fixes: 4dfe323 ("perf/x86: Add dynamic constraint")

Link: #1356
[Backport: drop arch/x86/include/asm/kvm_host.h for no rename it]

Summary by Sourcery

Maintain kABI compatibility for Intel PMU CWF support by moving new perf event fields into an extension struct and wiring it through allocation and usage paths.

Bug Fixes:

  • Prevent kABI breakage from new hw_perf_event fields by storing config1 and dyn_constraint in a separate extension structure referenced via a reserved perf_event field.

Enhancements:

  • Allocate and free a dedicated slab cache for the new hw_perf_event_ext structure used by perf events.

Intel inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/intel-kernel/issues/ICZHEB
CVE: NA

--------------------------------

Following upstream commits introduced 2 fields (config1 and dyn_constraint)
in struct hw_perf_event, which breaks kABI.

	ec980e4 ("perf/x86/intel: Support auto counter reload")
	4dfe323 ("perf/x86: Add dynamic constraint")

To fix this kABI breakage, we introduce struct hw_perf_event_ext, and
use one KABI_RESERVE field in struct perf_event as pointer to this
struct hw_perf_event_ext. This is viable because hw_perf_event is
always embedded in struct perf_event, so we can always access
hw_perf_event_ext from perf_event when needed.

We also create a kmem_cache for struct hw_per_event_ext.

Another kABI changes are caused by the following commit:

	0e102ce ("KVM: x86/pmu: Change ambiguous _mask suffix to _rsvd in kvm_pmu")

But the fix is trivial.

Fixes: ec980e4 ("perf/x86/intel: Support auto counter reload")
Fixes: 4dfe323 ("perf/x86: Add dynamic constraint")
Signed-off-by: Jason Zeng <[email protected]>
Link: deepin-community#1356
[Backport: drop arch/x86/include/asm/kvm_host.h for no rename it]
Signed-off-by: Wentao Guan <[email protected]>
@sourcery-ai
Copy link

sourcery-ai bot commented Dec 16, 2025

Reviewer's Guide

Introduces a kABI-safe extension structure for perf event hardware fields used by Intel CWF PMU (config1 and dyn_constraint), wiring it through perf core allocation/free paths and updating x86 PMU code to use the new extension pointer instead of embedding these fields directly in struct hw_perf_event.

Sequence diagram for perf_event and hw_perf_event_ext allocation and free

sequenceDiagram
    participant Init as perf_event_init
    participant Alloc as perf_event_alloc
    participant Free as free_event_rcu
    participant PEC as perf_event_cache
    participant PHC as perf_hw_event_cache

    Init->>PEC: perf_event_cache = KMEM_CACHE(perf_event, SLAB_PANIC)
    Init->>PHC: perf_hw_event_cache = KMEM_CACHE(hw_perf_event_ext, SLAB_PANIC)

    Alloc->>PEC: kmem_cache_alloc_node(perf_event_cache, GFP_KERNEL, node)
    PEC-->>Alloc: perf_event* event
    Alloc->>PHC: kmem_cache_alloc_node(perf_hw_event_cache, GFP_KERNEL|__GFP_ZERO, node)
    PHC-->>Alloc: hw_perf_event_ext* hw_ext
    Alloc->>Alloc: event->hw_ext = hw_ext
    Alloc->>Alloc: event->hw_ext->dyn_constraint = ~0ULL

    Free->>Free: perf_event_free_filter(event)
    Free->>PHC: kmem_cache_free(perf_hw_event_cache, event->hw_ext)
    Free->>PEC: kmem_cache_free(perf_event_cache, event)
Loading

Class diagram for kABI-safe perf event hardware extension

classDiagram
    class perf_event {
        +u32 orig_type
        +hw_perf_event hw
        +hw_perf_event_ext* hw_ext
    }

    class hw_perf_event {
        +u64 config
        +u64 last_tag
        +unsigned long config_base
        +unsigned long event_base
        +int event_base_rdpmc
        +int idx
        +int last_cpu
        +u64 sample_period
        +u64 period_left
        +u64 interrupt_period
        +u64 interrupts
        +u64 prev_count
        +u64 period
        +u64 pwritten
        +u32 state
        +u16 extra_reg_idx
        +u16 branch_reg_idx
        +unsigned long flags
        +u64 addr_filters
    }

    class hw_perf_event_ext {
        +u64 config1
        +u64 dyn_constraint
    }

    class kmem_cache {
        +void* objects
    }

    perf_event --> hw_perf_event : embeds
    perf_event --> hw_perf_event_ext : hw_ext

    kmem_cache <.. perf_event : perf_event_cache
    kmem_cache <.. hw_perf_event_ext : perf_hw_event_cache
Loading

File-Level Changes

Change Details Files
Introduce hw_perf_event_ext and reference it from perf_event using a DEEPIN_KABI_USE reserved slot.
  • Define struct hw_perf_event_ext containing config1 and dyn_constraint under CONFIG_PERF_EVENTS.
  • Remove config1 and dyn_constraint fields from struct hw_perf_event to restore its original kABI layout.
  • Change struct perf_event to use DEEPIN_KABI_USE(1) as a struct hw_perf_event_ext *hw_ext pointer instead of a generic reserve slot.
include/linux/perf_event.h
Allocate and manage lifetime of the new hw_perf_event_ext objects via a dedicated slab cache.
  • Add a global kmem_cache *perf_hw_event_cache for hw_perf_event_ext.
  • Create perf_hw_event_cache in perf_event_init using KMEM_CACHE(hw_perf_event_ext, SLAB_PANIC).
  • Allocate event->hw_ext from perf_hw_event_cache in perf_event_alloc and free it in free_event_rcu.
kernel/events/core.c
Update x86 PMU and Intel core PMU code to use hw_perf_event_ext fields instead of struct hw_perf_event fields.
  • Initialize event->hw_ext->dyn_constraint to ~0ULL in __x86_pmu_event_init instead of event->hw.dyn_constraint.
  • Use event->hw_ext in Intel PMU ACR configuration and bitmask operations (config1).
  • Use event->hw_ext->dyn_constraint when applying and updating dynamic constraints in Intel PMU constraint handling code.
arch/x86/events/core.c
arch/x86/events/intel/core.c

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@deepin-ci-robot
Copy link

deepin pr auto review

这是一个关于Linux内核性能事件(perf_event)子系统的代码变更审查。我来从多个角度分析这个改动:

  1. 语法逻辑分析:
  • 代码变更主要将hw_perf_event结构中的config1和dyn_constraint字段移到了新的hw_perf_event_ext结构中
  • 通过event->hw_ext指针访问这些字段,而不是直接访问event->hw
  • 语法上没有问题,逻辑上是合理的重构
  1. 代码质量改进:
  • 优点:
    • 通过分离扩展字段到独立结构,提高了代码的模块化
    • 使用DEEPIN_KABI_USE宏来管理KABI兼容性
    • 新增了专用的内存缓存perf_hw_event_cache来管理hw_perf_event_ext对象
  • 建议:
    • 可以考虑在hw_perf_event_ext结构中添加注释说明其用途
    • 建议在访问hw_ext指针时添加空指针检查,尽管在当前代码中已经做了初始化检查
  1. 性能影响:
  • 负面影响:
    • 增加了一层间接访问(通过指针),可能会轻微影响性能
    • 额外的内存分配和释放操作
  • 正面影响:
    • 通过专用缓存池管理内存,可能提高内存分配效率
    • 更好的缓存局部性(如果hw_perf_event_ext结构设计合理)
  1. 安全性考虑:
  • 内存管理:
    • 在perf_event_alloc中正确处理了内存分配失败的情况
    • 在free_event_rcu中正确释放了hw_ext内存
  • 建议:
    • 考虑在访问hw_ext指针时添加断言或检查
    • 可以考虑使用RCU机制来保护hw_ext的访问
  1. 其他建议:
  • 考虑添加文档说明这次重构的目的和影响
  • 可以考虑将hw_perf_event_ext的定义移到更合适的位置,比如与hw_perf_event定义放在一起
  • 建议在相关函数中添加注释说明为什么需要访问hw_ext而不是hw

总的来说,这是一个合理的重构,提高了代码的模块化程度,但需要确保正确处理了所有边界情况和错误条件。建议在合并前进行充分的测试,特别是在内存压力和高并发场景下的测试。

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there - I've reviewed your changes - here's some feedback:

  • Several call sites now unconditionally dereference event->hw_ext (e.g., in intel_pmu_enable_acr, intel_get_event_constraints, __x86_pmu_event_init); consider adding assertions or defensive checks, or clearly documenting that all perf events must go through perf_event_alloc so hw_ext is always initialized and never NULL.
  • perf_hw_event_cache is allocated in perf_event_init but used in free_event_rcu and perf_event_alloc; please double‑check that no perf events can be allocated or freed before perf_event_init runs, and that all perf event free paths (not only free_event_rcu) go through the new kmem_cache_free(perf_hw_event_cache, event->hw_ext).
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Several call sites now unconditionally dereference `event->hw_ext` (e.g., in `intel_pmu_enable_acr`, `intel_get_event_constraints`, `__x86_pmu_event_init`); consider adding assertions or defensive checks, or clearly documenting that all perf events must go through `perf_event_alloc` so `hw_ext` is always initialized and never NULL.
- `perf_hw_event_cache` is allocated in `perf_event_init` but used in `free_event_rcu` and `perf_event_alloc`; please double‑check that no perf events can be allocated or freed before `perf_event_init` runs, and that all perf event free paths (not only `free_event_rcu`) go through the new `kmem_cache_free(perf_hw_event_cache, event->hw_ext)`.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@lanlanxiyiji lanlanxiyiji merged commit 527ec89 into deepin-community:linux-6.6.y Dec 16, 2025
12 checks passed
@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: lanlanxiyiji, shy129
Once this PR has been reviewed and has the lgtm label, please ask for approval from opsiff. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes kernel ABI (kABI) breakage introduced by upstream commits that added config1 and dyn_constraint fields to struct hw_perf_event. To maintain kABI compatibility, these fields are moved to a new struct hw_perf_event_ext structure, which is allocated separately and accessed through a pointer stored in a reserved DEEPIN_KABI field in struct perf_event.

Key Changes

  • Created hw_perf_event_ext structure to hold config1 and dyn_constraint fields
  • Added dedicated kmem_cache for hw_perf_event_ext allocation
  • Updated all field accesses from event->hw.field to event->hw_ext->field in x86 PMU code

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
include/linux/perf_event.h Defines hw_perf_event_ext struct, removes fields from hw_perf_event, uses DEEPIN_KABI_USE macro for hw_ext pointer
kernel/events/core.c Adds kmem_cache for hw_perf_event_ext, allocates/frees extension structure
arch/x86/events/core.c Updates dyn_constraint initialization to use hw_ext
arch/x86/events/intel/core.c Updates all config1 and dyn_constraint references to use hw_ext pointer

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +155 to +160
union {
struct {
u64 config1;
u64 dyn_constraint;
};
};
Copy link

Copilot AI Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The union wrapper around the struct fields serves no purpose since there's only one member in the union. Consider removing the union and keeping only the struct with config1 and dyn_constraint fields. This would simplify the code structure without affecting functionality.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants