On 1/21/2026 5:58 AM, Chen, Zide wrote:
>
> On 1/18/2026 7:30 PM, Mi, Dapeng wrote:
>> On 1/17/2026 9:10 AM, Zide Chen wrote:
>>> Populate selected PEBS feature names in FEAT_PERF_CAPABILITIES to make
>>> the corresponding bits user-visible CPU feature knobs, allowing them to
>>> be explicitly enabled or disabled via -cpu +/-<feature>.
>>>
>>> Once named, these bits become part of the guest CPU configuration
>>> contract. If a VM is configured with such a feature enabled, migration
>>> to a destination that does not support the feature may fail, as the
>>> destination cannot honor the guest-visible CPU model.
>>>
>>> The PEBS_FMT bits are intentionally not exposed. They are not meaningful
>>> as user-visible features, and QEMU registers CPU features as boolean
>>> QOM properties, which makes them unsuitable for representing and
>>> checking numeric capabilities.
>> Currently KVM supports user space sets PEBS_FMT (see vmx_set_msr()), but
>> just requires the guest PEBS_FMT is identical with host PEBS_FMT.
> My mistake — this is indeed problematic.
>
> There are four possible ways to expose pebs_fmt to the guest when
> cpu->migratable = true:
>
> 1. Add a pebs_fmt option similar to lbr_fmt.
> This may work, but is not user-friendly and adds unnecessary complexity.
>
> 2. Set feat_names[8] = feat_names[9] = ... = "pebs-fmt".
> This violates the implicit rule that feat_names[] entries should be
> unique, and target/i386 does not support numeric features.
>
> 3. Use feat_names[8..11] = "pebs-fmt[1/2/3/4]".
> This has two issues:
> - It exposes pebs-fmt[1/2/3/4] as independent features, which is
> semantically incorrect.
> - Migration may fail incorrectly; e.g., migrating from pebs_fmt=2 to a
> more capable host (pebs_fmt=4) would be reported as missing pebs-fmt2.
>
> Given this, I propose the below changes. This may allow migration to a
> less capable destination, which is not ideal, but it avoids false
> “missing feature” bug and preserves the expectation that ensuring
> destination compatibility is the responsibility of the management
> application or the user.
>
> BTW, I am not proposing a generic “x86 CPU numeric feature” mechanism at
> this time, as it is unclear whether lbr_fmt and pebs_fmt alone justify
> such a change.
>
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index 015ba3fc9c7b..b6c95d5ceb31 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -1629,6 +1629,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
> .msr = {
> .index = MSR_IA32_PERF_CAPABILITIES,
> },
> + .migratable_flags = PERF_CAP_PEBS_FMT,
> },
>
> [FEAT_VMX_PROCBASED_CTLS] = {
> diff --git a/target/i386/cpu.h b/target/i386/cpu.h
> index 1666eff65300..de4074d6baa7 100644
> --- a/target/i386/cpu.h
> +++ b/target/i386/cpu.h
> @@ -421,6 +421,7 @@ typedef enum X86Seg {
>
> #define MSR_IA32_PERF_CAPABILITIES 0x345
> #define PERF_CAP_LBR_FMT 0x3f
> +#define PERF_CAP_PEBS_FMT 0xf00
> #define PERF_CAP_FULL_WRITE (1U << 13)
> #define PERF_CAP_PEBS_BASELINE (1U << 14)
I can't say if this is the best way. Maybe @Zhao can give some comments.
Thanks.
>
>
>> IIRC, many places in KVM judges whether guest PEBS is enabled by checking
>> the guest PEBS_FMT. If we don't expose PEBS_FMT to user space, how does KVM
>> get the guest PEBS_FMT?
>>
>>
>>> Co-developed-by: Dapeng Mi <[email protected]>
>>> Signed-off-by: Dapeng Mi <[email protected]>
>>> Signed-off-by: Zide Chen <[email protected]>
>>> ---
>>> target/i386/cpu.c | 6 +++---
>>> 1 file changed, 3 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
>>> index f1ac98970d3e..fc6a64287415 100644
>>> --- a/target/i386/cpu.c
>>> +++ b/target/i386/cpu.c
>>> @@ -1618,10 +1618,10 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
>>> .type = MSR_FEATURE_WORD,
>>> .feat_names = {
>>> NULL, NULL, NULL, NULL,
>>> + NULL, NULL, "pebs-trap", "pebs-arch-reg"
>>> NULL, NULL, NULL, NULL,
>>> - NULL, NULL, NULL, NULL,
>>> - NULL, "full-width-write", NULL, NULL,
>>> - NULL, NULL, NULL, NULL,
>>> + NULL, "full-width-write", "pebs-baseline", NULL,
>>> + NULL, "pebs-timing-info", NULL, NULL,
>>> NULL, NULL, NULL, NULL,
>>> NULL, NULL, NULL, NULL,
>>> NULL, NULL, NULL, NULL,
>