Re: [PATCH 4/5] x86/apic: Introduce a variable to track the number of EILVT registers

From: Naveen N Rao

Date: Wed Apr 08 2026 - 06:32:30 EST


On Wed, Apr 01, 2026 at 10:26:35AM +0530, Naveen N Rao (AMD) wrote:
> Future AMD processors will be increasing the number of EILVT registers.
> Rather than hardcoding the maximum EILVT register count and using that
> everywhere, introduce a variable to track the EILVT register count.
>
> The number of EILVT registers is exposed through the extended APIC
> Feature Register (APIC_EFEAT) bits 23:16. Use this to initialize the
> count and fall back to the current default (APIC_EILVT_NR_AMD_10H) if
> the count is not available.
>
> Export the new variable for KVM since it needs this for supporting
> extended APIC register space on AMD.
>
> Signed-off-by: Naveen N Rao (AMD) <naveen@xxxxxxxxxx>
> Tested-by: Manali Shukla <manali.shukla@xxxxxxx>
> ---
> http://lore.kernel.org/r/20260204074452.55453-3-manali.shukla@xxxxxxx as
> a related series adding support for KVM and needing access to the EILVT
> register count.
>

...

>
> +static __init void init_eilvt(void)
> +{
> + if (cpu_feature_enabled(X86_FEATURE_EXTAPIC))
> + apic_eilvt_count = APIC_EFEAT_XLC(apic_read(APIC_EFEAT));
> +
> + if (!apic_eilvt_count)
> + apic_eilvt_count = APIC_EILVT_NR_AMD_10H;
> +}
> +
> /*
> * Program the next event, relative to now
> */
> @@ -1644,6 +1655,9 @@ static void setup_local_APIC(void)
> if (!cpu)
> cmci_recheck();
> #endif
> +
> + if (!apic_eilvt_count)
> + init_eilvt();
> }

Kernel Test Robot (lkp@xxxxxxxxx) reported that we will now be calling
into an __init function from a non-init function. So, I'm thinking I
should move this into apic_bsp_setup() instead:

diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 748e09c5b322..fc8be361e51a 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -1655,9 +1655,6 @@ static void setup_local_APIC(void)
if (!cpu)
cmci_recheck();
#endif
-
- if (!apic_eilvt_count)
- init_eilvt();
}

static void end_local_APIC_setup(void)
@@ -2357,6 +2354,7 @@ static void __init apic_bsp_setup(bool upmode)
if (upmode)
apic_bsp_up_setup();
setup_local_APIC();
+ init_eilvt();

enable_IO_APIC();
end_local_APIC_setup();


Since that is now only called on the BSP, we can also ensure that
apic_eilvt_count is only set on AMD processors (avoids having to
allocate memory for eilvt_offsets otherwise):

diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index ada963d90659..ca29be202d81 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -416,10 +416,10 @@ static __init void init_eilvt(void)
if (cpu_feature_enabled(X86_FEATURE_EXTAPIC))
apic_eilvt_count = APIC_EFEAT_XLC(apic_read(APIC_EFEAT));

- if (!apic_eilvt_count)
+ if (!apic_eilvt_count && boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
apic_eilvt_count = APIC_EILVT_NR_AMD_10H;

- if (!eilvt_offsets)
+ if (apic_eilvt_count)
eilvt_offsets = kzalloc_objs(atomic_t, apic_eilvt_count);
}


Thoughts?


- Naveen