--- zzzz-none-000/linux-4.9.279/arch/x86/kernel/apic/io_apic.c 2021-08-08 06:38:54.000000000 +0000 +++ puma7-atom-6591-750/linux-4.9.279/arch/x86/kernel/apic/io_apic.c 2023-02-08 11:43:42.000000000 +0000 @@ -3034,3 +3034,53 @@ .activate = mp_irqdomain_activate, .deactivate = mp_irqdomain_deactivate, }; + +#if IS_ENABLED(CONFIG_AVM_ENHANCED) +int IO_APIC_enable_nmi(int irq, const cpumask_t *mask) +{ + struct mp_chip_data *data; + struct irq_pin_list *pin; + struct IO_APIC_route_entry entry; + unsigned int dest; + unsigned long flags; + int result; + + result = 0; + + if (cpumask_empty(mask)) { + result = -EINVAL; + goto err_out; + } + apic->cpu_mask_to_apicid_and(mask, mask, &dest); + + data = irq_get_chip_data(irq); + if (!data) { + result = -EINVAL; + goto err_out; + } + + raw_spin_lock_irqsave(&ioapic_lock, flags); + + /* TODO: somehow save pin config(s) for restore on disable. */ + for_each_irq_pin(pin, data->irq_2_pin) { + entry = __ioapic_read_entry(pin->apic, pin->pin); + entry.dest = dest; + entry.delivery_mode = APIC_MODE_NMI; + entry.dest_mode = 1; /* logical, i.e. target mask */ + __ioapic_write_entry(pin->apic, pin->pin, entry); + } + + raw_spin_unlock_irqrestore(&ioapic_lock, flags); + +err_out: + return result; +} +EXPORT_SYMBOL(IO_APIC_enable_nmi); + +int IO_APIC_disable_nmi(int irq) +{ + /* TODO: either restore to default or do an explicit save/restore. */ + return 0; +} +EXPORT_SYMBOL(IO_APIC_disable_nmi); +#endif /* IS_ENABLED(CONFIG_AVM_ENHANCED) */