From: Naveen N Rao <naveen@kernel.org>
To: Manali Shukla <manali.shukla@amd.com>
Cc: seanjc@google.com, pbonzini@redhat.com, mingo@redhat.com,
bp@alien8.de, dave.hansen@linux.intel.com, kvm@vger.kernel.org,
x86@kernel.org, santosh.shukla@amd.com, nikunj.dadhania@amd.com,
dapeng1.mi@linux.intel.com
Subject: Re: [PATCH v1 7/9] KVM: x86: Emulate Extended LVT registers for AMD guests
Date: Thu, 14 May 2026 20:18:28 +0530 [thread overview]
Message-ID: <agXfdJ_gnujR3k8Z@blrnaveerao1> (raw)
In-Reply-To: <20260204074452.55453-8-manali.shukla@amd.com>
On Wed, Feb 04, 2026 at 07:44:50AM +0000, Manali Shukla wrote:
> From: Santosh Shukla <santosh.shukla@amd.com>
>
> Emulate reads and writes to AMD Extended APIC registers: APIC_EFEAT
> (0x400), APIC_ECTRL (0x410), and APIC_EILVTn (0x500-0x530). Without
> emulation, Instruction Based Sampling (IBS) driver fails to initialize
> when it tries to access APIC_EILVT(0).
>
> Extend the LAPIC register read and write paths to allow accesses beyond
> the standard 0x3f0 offset when the guest has X86_FEATURE_EXTAPIC. The
> valid range is determined by kvm->arch.nr_extlvt, which userspace
> configures via KVM_CAP_LAPIC2.
>
> Initialize extended APIC registers in both kvm_vcpu_after_set_cpuid()
> and kvm_lapic_reset(). The initial kvm_lapic_reset() occurs before
> userspace configures CPUID via KVM_SET_CPUID2, so extended LVT registers
> can't be initialized until X86_FEATURE_EXTAPIC is set. Handle the
> initial setup in kvm_vcpu_after_set_cpuid() and subsequent resets in
> kvm_lapic_reset().
>
> Initialize APIC_EFEAT to report the number of extended LVTs (read-only).
> Initialize APIC_ECTRL to zero (read-write). Initialize APIC_EILVTn
> entries to masked (bit 16 set), matching hardware reset behavior.
>
> Please refer to Section 16.4.5 in AMD Programmer's Manual Volume 2 at
> https://bugzilla.kernel.org/attachment.cgi?id=306250 for more details
> on Extended LVT.
>
> Signed-off-by: Santosh Shukla <santosh.shukla@amd.com>
> Co-developed-by: Manali Shukla <manali.shukla@amd.com>
> Signed-off-by: Manali Shukla <manali.shukla@amd.com>
> ---
> arch/x86/include/asm/apicdef.h | 18 ++++++++++++++
> arch/x86/kvm/cpuid.c | 10 +++++++-
> arch/x86/kvm/lapic.c | 43 ++++++++++++++++++++++++++++++++++
> arch/x86/kvm/lapic.h | 8 +++++++
> 4 files changed, 78 insertions(+), 1 deletion(-)
>
> diff --git a/arch/x86/include/asm/apicdef.h b/arch/x86/include/asm/apicdef.h
> index be39a543fbe5..5c5e9db1e27d 100644
> --- a/arch/x86/include/asm/apicdef.h
> +++ b/arch/x86/include/asm/apicdef.h
> @@ -148,6 +148,24 @@
> #define APIC_EILVT_MSG_EXT 0x7
> #define APIC_EILVT_MASKED (1 << 16)
>
> +/*
> + * Initialize extended APIC registers to the default value when guest
> + * is started and EXTAPIC feature is enabled on the guest.
> + *
> + * APIC_EFEAT is a read only Extended APIC feature register, whose bits
> + * 0, 1, and 2 represent features that are not currently emulated by KVM.
> + * Therefore, these bits must be cleared during initialization. As a result, the
> + * default value used for APIC_EFEAT in KVM is set based on number of extended
> + * LVT registers supported by the guest.
> + *
> + * APIC_ECTRL is a read-write Extended APIC control register, whose
> + * default value is 0x0.
> + */
> +
> +#define APIC_EFEAT_MASK 0x00FF0000
> +#define APIC_EFEAT_DEFAULT(n) ((n << 16) & APIC_EFEAT_MASK)
> +#define APIC_ECTRL_DEFAULT 0x0
> +
This probably belongs in the KVM headers.
> #define APIC_BASE (fix_to_virt(FIX_APIC_BASE))
> #define APIC_BASE_MSR 0x800
> #define APIC_X2APIC_ID_MSR 0x802
> diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
> index baa1cf473d45..4574149d137b 100644
> --- a/arch/x86/kvm/cpuid.c
> +++ b/arch/x86/kvm/cpuid.c
> @@ -435,6 +435,14 @@ void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
> kvm_apic_set_version(vcpu);
> }
>
> + /*
> + * Initialize extended APIC registers after CPUID is set. The initial
> + * reset occurs before userspace configures CPUID, so extended LVT
> + * registers (which require X86_FEATURE_EXTAPIC) can't be initialized
> + * until after KVM_SET_CPUID2.
> + */
> + kvm_apic_init_extlvt_regs(vcpu);
> +
> vcpu->arch.guest_supported_xcr0 = cpuid_get_supported_xcr0(vcpu);
> vcpu->arch.guest_supported_xss = cpuid_get_supported_xss(vcpu);
>
> @@ -1076,7 +1084,7 @@ void kvm_set_cpu_caps(void)
> F(LAHF_LM),
> F(CMP_LEGACY),
> VENDOR_F(SVM),
> - /* ExtApicSpace */
> + F(EXTAPIC),
Shouldn't this be VENDOR_F()?
> F(CR8_LEGACY),
> F(ABM),
> F(SSE4A),
> diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
> index 4ed6abb414e4..a04c808289c3 100644
> --- a/arch/x86/kvm/lapic.c
> +++ b/arch/x86/kvm/lapic.c
> @@ -1687,6 +1687,7 @@ static inline struct kvm_lapic *to_lapic(struct kvm_io_device *dev)
> test_bit(APIC_REG_TO_BIT(reg), (unsigned long *)(mask))
>
> #define APIC_LAST_REG_OFFSET 0x3f0
> +#define APIC_EXT_LAST_REG_OFFSET(n) APIC_EILVTn((n))
>
> void kvm_lapic_readable_reg_mask(struct kvm_lapic *apic, u64 mask[2])
> {
> @@ -1722,6 +1723,12 @@ void kvm_lapic_readable_reg_mask(struct kvm_lapic *apic, u64 mask[2])
> APIC_REG_MASK(APIC_DFR, mask);
> APIC_REG_MASK(APIC_ICR2, mask);
> }
> +
> + if (guest_cpu_cap_has(apic->vcpu, X86_FEATURE_EXTAPIC)) {
> + APIC_REG_MASK(APIC_EFEAT, mask);
> + APIC_REG_MASK(APIC_ECTRL, mask);
> + APIC_REGS_MASK(APIC_EILVTn(0), apic->vcpu->kvm->arch.nr_extlvt, mask);
> + }
> }
> EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_lapic_readable_reg_mask);
>
> @@ -1739,6 +1746,13 @@ static int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset, int len,
> */
> WARN_ON_ONCE(apic_x2apic_mode(apic) && offset == APIC_ICR);
>
> + if (guest_cpu_cap_has(apic->vcpu, X86_FEATURE_EXTAPIC)) {
> + u8 nr_extlvt = apic->vcpu->kvm->arch.nr_extlvt;
> +
> + if (nr_extlvt > 0)
> + last_reg = APIC_EXT_LAST_REG_OFFSET(nr_extlvt - 1);
> + }
> +
We should be able to eliminate the need for this if we have
kvm_lapic_readable_reg_mask() work with the full 4k APIC page:
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 8f4b63c9807b..ed20e0b21be7 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -1736,9 +1736,6 @@ static inline struct kvm_lapic *to_lapic(struct kvm_io_device *dev)
#define APIC_REGS_MASK(first, count, mask) bitmap_set(mask, APIC_REG_TO_BIT(first), (count))
#define APIC_REG_TEST(reg, mask) test_bit(APIC_REG_TO_BIT(reg), (unsigned long *)(mask))
-#define APIC_LAST_REG_OFFSET 0x3f0
-#define APIC_EXT_LAST_REG_OFFSET(n) APIC_EILVTn((n))
-
void kvm_lapic_readable_reg_mask(struct kvm_lapic *apic, unsigned long *mask)
{
bitmap_zero(mask, APIC_REG_BITMAP_BITS);
@@ -1785,7 +1782,6 @@ EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_lapic_readable_reg_mask);
static int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset, int len,
void *data)
{
- unsigned int last_reg = APIC_LAST_REG_OFFSET;
DECLARE_BITMAP(mask, APIC_REG_BITMAP_BITS);
unsigned char alignment = offset & 0xf;
u32 result;
@@ -1796,19 +1792,12 @@ static int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset, int len,
*/
WARN_ON_ONCE(apic_x2apic_mode(apic) && offset == APIC_ICR);
- if (guest_cpu_cap_has(apic->vcpu, X86_FEATURE_EXTAPIC)) {
- u8 nr_extlvt = apic->vcpu->kvm->arch.nr_extlvt;
-
- if (nr_extlvt > 0)
- last_reg = APIC_EXT_LAST_REG_OFFSET(nr_extlvt - 1);
- }
-
if (alignment + len > 4)
return 1;
kvm_lapic_readable_reg_mask(apic, mask);
- if (offset > last_reg || !APIC_REG_TEST(offset, mask))
+ if (APIC_REG_TO_BIT(offset) >= APIC_REG_BITMAP_BITS || !APIC_REG_TEST(offset, mask))
return 1;
result = __apic_read(apic, offset & ~0xf);
- Naveen
next prev parent reply other threads:[~2026-05-14 14:49 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-04 7:44 [PATCH v1 0/9] KVM: x86: Add support for AMD Extended APIC registers Manali Shukla
2026-02-04 7:44 ` [PATCH v1 1/9] KVM: x86: Refactor APIC register mask handling to support extended " Manali Shukla
2026-05-14 12:48 ` Naveen N Rao
2026-02-04 7:44 ` [PATCH v1 2/9] x86/apic: Add helper to get maximum number of Extended LVT registers Manali Shukla
2026-05-06 11:22 ` Borislav Petkov
2026-05-14 12:50 ` Naveen N Rao
2026-02-04 7:44 ` [PATCH v1 3/9] KVM: SVM: Set kvm_caps.has_extapic when CPU supports Extended APIC Manali Shukla
2026-05-14 12:58 ` Naveen N Rao
2026-02-04 7:44 ` [PATCH v1 4/9] KVM: x86: Introduce KVM_CAP_LAPIC2 for 4KB APIC register space support Manali Shukla
2026-05-14 13:08 ` Naveen N Rao
2026-02-04 7:44 ` [PATCH v1 5/9] KVM: x86: Refactor APIC state get/set to accept variable-sized buffers Manali Shukla
2026-05-14 14:20 ` Naveen N Rao
2026-02-04 7:44 ` [PATCH v1 6/9] KVM: Add KVM_GET_LAPIC2 and KVM_SET_LAPIC2 for extended APIC Manali Shukla
2026-03-16 13:00 ` Nikunj A. Dadhania
2026-03-23 11:15 ` Manali Shukla
2026-05-14 14:36 ` Naveen N Rao
2026-05-14 14:41 ` Naveen N Rao
2026-02-04 7:44 ` [PATCH v1 7/9] KVM: x86: Emulate Extended LVT registers for AMD guests Manali Shukla
2026-05-14 14:48 ` Naveen N Rao [this message]
2026-02-04 7:44 ` [PATCH v1 8/9] x86/cpufeatures: Add CPUID feature bit for Extended LVT AVIC acceleration Manali Shukla
2026-02-04 7:44 ` [PATCH v1 9/9] KVM: SVM: Add AVIC support for extended LVT MSRs Manali Shukla
2026-05-14 15:10 ` Naveen N Rao
2026-03-10 6:17 ` [PATCH v1 0/9] KVM: x86: Add support for AMD Extended APIC registers Manali Shukla
2026-04-27 4:34 ` Shukla, Manali
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=agXfdJ_gnujR3k8Z@blrnaveerao1 \
--to=naveen@kernel.org \
--cc=bp@alien8.de \
--cc=dapeng1.mi@linux.intel.com \
--cc=dave.hansen@linux.intel.com \
--cc=kvm@vger.kernel.org \
--cc=manali.shukla@amd.com \
--cc=mingo@redhat.com \
--cc=nikunj.dadhania@amd.com \
--cc=pbonzini@redhat.com \
--cc=santosh.shukla@amd.com \
--cc=seanjc@google.com \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.