Skip to content

Commit 8f4a29b

Browse files
xinli-intelbp3tk0v
authored andcommitted
x86/traps: Add sysvec_install() to install a system interrupt handler
Add sysvec_install() to install a system interrupt handler into the IDT or the FRED system interrupt handler table. Signed-off-by: Xin Li <xin3.li@intel.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> Tested-by: Shan Kang <shan.kang@intel.com> Link: https://lore.kernel.org/r/20231205105030.8698-28-xin3.li@intel.com
1 parent 14619d9 commit 8f4a29b

8 files changed

Lines changed: 42 additions & 16 deletions

File tree

arch/x86/entry/entry_fred.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,20 @@ static idtentry_t sysvec_table[NR_SYSTEM_VECTORS] __ro_after_init = {
119119
SYSVEC(POSTED_INTR_NESTED_VECTOR, kvm_posted_intr_nested_ipi),
120120
};
121121

122+
static bool fred_setup_done __initdata;
123+
124+
void __init fred_install_sysvec(unsigned int sysvec, idtentry_t handler)
125+
{
126+
if (WARN_ON_ONCE(sysvec < FIRST_SYSTEM_VECTOR))
127+
return;
128+
129+
if (WARN_ON_ONCE(fred_setup_done))
130+
return;
131+
132+
if (!WARN_ON_ONCE(sysvec_table[sysvec - FIRST_SYSTEM_VECTOR]))
133+
sysvec_table[sysvec - FIRST_SYSTEM_VECTOR] = handler;
134+
}
135+
122136
static noinstr void fred_extint(struct pt_regs *regs)
123137
{
124138
unsigned int vector = regs->fred_ss.vector;

arch/x86/include/asm/desc.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,8 +402,6 @@ static inline void set_desc_limit(struct desc_struct *desc, unsigned long limit)
402402
desc->limit1 = (limit >> 16) & 0xf;
403403
}
404404

405-
void alloc_intr_gate(unsigned int n, const void *addr);
406-
407405
static inline void init_idt_data(struct idt_data *data, unsigned int n,
408406
const void *addr)
409407
{

arch/x86/include/asm/idtentry.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,21 @@ __visible noinstr void func(struct pt_regs *regs, \
459459
#define DEFINE_FREDENTRY_DEBUG DEFINE_FREDENTRY_RAW
460460
#endif
461461

462+
void idt_install_sysvec(unsigned int n, const void *function);
463+
464+
#ifdef CONFIG_X86_FRED
465+
void fred_install_sysvec(unsigned int vector, const idtentry_t function);
466+
#else
467+
static inline void fred_install_sysvec(unsigned int vector, const idtentry_t function) { }
468+
#endif
469+
470+
#define sysvec_install(vector, function) { \
471+
if (cpu_feature_enabled(X86_FEATURE_FRED)) \
472+
fred_install_sysvec(vector, function); \
473+
else \
474+
idt_install_sysvec(vector, asm_##function); \
475+
}
476+
462477
#else /* !__ASSEMBLY__ */
463478

464479
/*

arch/x86/kernel/cpu/acrn.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ static u32 __init acrn_detect(void)
2626

2727
static void __init acrn_init_platform(void)
2828
{
29-
/* Setup the IDT for ACRN hypervisor callback */
30-
alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, asm_sysvec_acrn_hv_callback);
29+
/* Install system interrupt handler for ACRN hypervisor callback */
30+
sysvec_install(HYPERVISOR_CALLBACK_VECTOR, sysvec_acrn_hv_callback);
3131

3232
x86_platform.calibrate_tsc = acrn_get_tsc_khz;
3333
x86_platform.calibrate_cpu = acrn_get_tsc_khz;

arch/x86/kernel/cpu/mshyperv.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -539,19 +539,18 @@ static void __init ms_hyperv_init_platform(void)
539539
*/
540540
x86_platform.apic_post_init = hyperv_init;
541541
hyperv_setup_mmu_ops();
542-
/* Setup the IDT for hypervisor callback */
543-
alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, asm_sysvec_hyperv_callback);
544542

545-
/* Setup the IDT for reenlightenment notifications */
543+
/* Install system interrupt handler for hypervisor callback */
544+
sysvec_install(HYPERVISOR_CALLBACK_VECTOR, sysvec_hyperv_callback);
545+
546+
/* Install system interrupt handler for reenlightenment notifications */
546547
if (ms_hyperv.features & HV_ACCESS_REENLIGHTENMENT) {
547-
alloc_intr_gate(HYPERV_REENLIGHTENMENT_VECTOR,
548-
asm_sysvec_hyperv_reenlightenment);
548+
sysvec_install(HYPERV_REENLIGHTENMENT_VECTOR, sysvec_hyperv_reenlightenment);
549549
}
550550

551-
/* Setup the IDT for stimer0 */
551+
/* Install system interrupt handler for stimer0 */
552552
if (ms_hyperv.misc_features & HV_STIMER_DIRECT_MODE_AVAILABLE) {
553-
alloc_intr_gate(HYPERV_STIMER0_VECTOR,
554-
asm_sysvec_hyperv_stimer0);
553+
sysvec_install(HYPERV_STIMER0_VECTOR, sysvec_hyperv_stimer0);
555554
}
556555

557556
# ifdef CONFIG_SMP

arch/x86/kernel/idt.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ void idt_invalidate(void)
337337
load_idt(&idt);
338338
}
339339

340-
void __init alloc_intr_gate(unsigned int n, const void *addr)
340+
void __init idt_install_sysvec(unsigned int n, const void *function)
341341
{
342342
if (WARN_ON(n < FIRST_SYSTEM_VECTOR))
343343
return;
@@ -346,5 +346,5 @@ void __init alloc_intr_gate(unsigned int n, const void *addr)
346346
return;
347347

348348
if (!WARN_ON(test_and_set_bit(n, system_vectors)))
349-
set_intr_gate(n, addr);
349+
set_intr_gate(n, function);
350350
}

arch/x86/kernel/kvm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -829,7 +829,7 @@ static void __init kvm_guest_init(void)
829829

830830
if (kvm_para_has_feature(KVM_FEATURE_ASYNC_PF_INT) && kvmapf) {
831831
static_branch_enable(&kvm_async_pf_enabled);
832-
alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, asm_sysvec_kvm_asyncpf_interrupt);
832+
sysvec_install(HYPERVISOR_CALLBACK_VECTOR, sysvec_kvm_asyncpf_interrupt);
833833
}
834834

835835
#ifdef CONFIG_SMP

drivers/xen/events/events_base.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2216,7 +2216,7 @@ static __init void xen_alloc_callback_vector(void)
22162216
return;
22172217

22182218
pr_info("Xen HVM callback vector for event delivery is enabled\n");
2219-
alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, asm_sysvec_xen_hvm_callback);
2219+
sysvec_install(HYPERVISOR_CALLBACK_VECTOR, sysvec_xen_hvm_callback);
22202220
}
22212221
#else
22222222
void xen_setup_callback_vector(void) {}

0 commit comments

Comments
 (0)