Add lapic_get_max_extlvt() to retrieve the maximum number of Extended LVT registers supported by the local APIC on AMD processors. The count is read from APIC_EFEAT[23:16] (offset 0x400), per AMD APM Volume 2. Extended LVT registers provide additional interrupt vectors beyond standard LVT entries, enabling features like Instruction Based Sampling (IBS). Current AMD processors support four extended LVT entries, but future processors may support up to 255. Wrap lapic_get_max_extlvt() with kvm_cpu_get_max_extlvt() for use by KVM code. Subsequent patches will use this helper to configure the guest's extended APIC register space. Signed-off-by: Manali Shukla --- arch/x86/include/asm/apic.h | 1 + arch/x86/include/asm/kvm_host.h | 10 ++++++++++ arch/x86/kernel/apic/apic.c | 17 +++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index a26e66d66444..d45696563a4e 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -128,6 +128,7 @@ static inline bool apic_is_x2apic_enabled(void) extern void enable_IR_x2apic(void); extern int lapic_get_maxlvt(void); +extern int lapic_get_max_extlvt(void); extern void clear_local_APIC(void); extern void disconnect_bsp_APIC(int virt_wire_setup); extern void disable_local_APIC(void); diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index ecd4019b84b7..df642723cea6 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -2461,6 +2461,16 @@ static inline int kvm_cpu_get_apicid(int mps_cpu) #endif } +static inline int kvm_cpu_get_max_extlvt(void) +{ +#ifdef CONFIG_X86_LOCAL_APIC + return lapic_get_max_extlvt(); +#else + WARN_ON_ONCE(1); + return 0; +#endif +} + int memslot_rmap_alloc(struct kvm_memory_slot *slot, unsigned long npages); #define KVM_CLOCK_VALID_FLAGS \ diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index d93f87f29d03..90992ae4852a 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -253,6 +253,23 @@ int lapic_get_maxlvt(void) return lapic_is_integrated() ? GET_APIC_MAXLVT(apic_read(APIC_LVR)) : 2; } +/** + * lapic_get_max_extlvt - Get number of extended LVT entries + */ +int lapic_get_max_extlvt(void) +{ + u32 reg; + + if (!boot_cpu_has(X86_FEATURE_EXTAPIC)) + return 0; + + reg = apic_read(APIC_EFEAT); + + /* Extract extended LVT count from bits 16-23 */ + return (reg >> 16) & 0xff; +} +EXPORT_SYMBOL_GPL(lapic_get_max_extlvt); + /* * Local APIC timer */ -- 2.43.0