1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 1992, 1998-2006 Linus Torvalds, Ingo Molnar 4 * Copyright (C) 2005-2006, Thomas Gleixner 5 * 6 * This file contains the IRQ-resend code 7 * 8 * If the interrupt is waiting to be processed, we try to re-run it. 9 * We can't directly run it from here since the caller might be in an 10 * interrupt-protected region. Not all irq controller chips can 11 * retrigger interrupts at the hardware level, so in those cases 12 * we allow the resending of IRQs via a tasklet. 13 */ 14 15 #include <linux/irq.h> 16 #include <linux/module.h> 17 #include <linux/random.h> 18 #include <linux/interrupt.h> 19 20 #include "internals.h" 21 22 #ifdef CONFIG_HARDIRQS_SW_RESEND 23 24 /* hlist_head to handle software resend of interrupts: */ 25 static HLIST_HEAD(irq_resend_list); 26 static DEFINE_RAW_SPINLOCK(irq_resend_lock); 27 28 /* 29 * Run software resends of IRQ's 30 */ 31 static void resend_irqs(struct tasklet_struct *unused) 32 { 33 struct irq_desc *desc; 34 35 raw_spin_lock_irq(&irq_resend_lock); 36 while (!hlist_empty(&irq_resend_list)) { 37 desc = hlist_entry(irq_resend_list.first, struct irq_desc, 38 resend_node); 39 hlist_del_init(&desc->resend_node); 40 raw_spin_unlock(&irq_resend_lock); 41 desc->handle_irq(desc); 42 raw_spin_lock(&irq_resend_lock); 43 } 44 raw_spin_unlock_irq(&irq_resend_lock); 45 } 46 47 /* Tasklet to handle resend: */ 48 static DECLARE_TASKLET(resend_tasklet, resend_irqs); 49 50 static int irq_sw_resend(struct irq_desc *desc) 51 { 52 /* 53 * Validate whether this interrupt can be safely injected from 54 * non interrupt context 55 */ 56 if (handle_enforce_irqctx(&desc->irq_data)) 57 return -EINVAL; 58 59 /* 60 * If the interrupt is running in the thread context of the parent 61 * irq we need to be careful, because we cannot trigger it 62 * directly. 63 */ 64 if (irq_settings_is_nested_thread(desc)) { 65 /* 66 * If the parent_irq is valid, we retrigger the parent, 67 * otherwise we do nothing. 68 */ 69 if (!desc->parent_irq) 70 return -EINVAL; 71 72 desc = irq_to_desc(desc->parent_irq); 73 if (!desc) 74 return -EINVAL; 75 } 76 77 /* Add to resend_list and activate the softirq: */ 78 raw_spin_lock(&irq_resend_lock); 79 if (hlist_unhashed(&desc->resend_node)) 80 hlist_add_head(&desc->resend_node, &irq_resend_list); 81 raw_spin_unlock(&irq_resend_lock); 82 tasklet_schedule(&resend_tasklet); 83 return 0; 84 } 85 86 void clear_irq_resend(struct irq_desc *desc) 87 { 88 raw_spin_lock(&irq_resend_lock); 89 hlist_del_init(&desc->resend_node); 90 raw_spin_unlock(&irq_resend_lock); 91 } 92 93 void irq_resend_init(struct irq_desc *desc) 94 { 95 INIT_HLIST_NODE(&desc->resend_node); 96 } 97 #else 98 void clear_irq_resend(struct irq_desc *desc) {} 99 void irq_resend_init(struct irq_desc *desc) {} 100 101 static int irq_sw_resend(struct irq_desc *desc) 102 { 103 return -EINVAL; 104 } 105 #endif 106 107 static int try_retrigger(struct irq_desc *desc) 108 { 109 if (desc->irq_data.chip->irq_retrigger) 110 return desc->irq_data.chip->irq_retrigger(&desc->irq_data); 111 112 #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY 113 return irq_chip_retrigger_hierarchy(&desc->irq_data); 114 #else 115 return 0; 116 #endif 117 } 118 119 /* 120 * IRQ resend 121 * 122 * Is called with interrupts disabled and desc->lock held. 123 */ 124 int check_irq_resend(struct irq_desc *desc, bool inject) 125 { 126 int err = 0; 127 128 /* 129 * We do not resend level type interrupts. Level type interrupts 130 * are resent by hardware when they are still active. Clear the 131 * pending bit so suspend/resume does not get confused. 132 */ 133 if (irq_settings_is_level(desc)) { 134 desc->istate &= ~IRQS_PENDING; 135 return -EINVAL; 136 } 137 138 if (desc->istate & IRQS_REPLAY) 139 return -EBUSY; 140 141 if (!(desc->istate & IRQS_PENDING) && !inject) 142 return 0; 143 144 desc->istate &= ~IRQS_PENDING; 145 146 if (!try_retrigger(desc)) 147 err = irq_sw_resend(desc); 148 149 /* If the retrigger was successful, mark it with the REPLAY bit */ 150 if (!err) 151 desc->istate |= IRQS_REPLAY; 152 return err; 153 } 154 155 #ifdef CONFIG_GENERIC_IRQ_INJECTION 156 /** 157 * irq_inject_interrupt - Inject an interrupt for testing/error injection 158 * @irq: The interrupt number 159 * 160 * This function must only be used for debug and testing purposes! 161 * 162 * Especially on x86 this can cause a premature completion of an interrupt 163 * affinity change causing the interrupt line to become stale. Very 164 * unlikely, but possible. 165 * 166 * The injection can fail for various reasons: 167 * - Interrupt is not activated 168 * - Interrupt is NMI type or currently replaying 169 * - Interrupt is level type 170 * - Interrupt does not support hardware retrigger and software resend is 171 * either not enabled or not possible for the interrupt. 172 */ 173 int irq_inject_interrupt(unsigned int irq) 174 { 175 struct irq_desc *desc; 176 unsigned long flags; 177 int err; 178 179 /* Try the state injection hardware interface first */ 180 if (!irq_set_irqchip_state(irq, IRQCHIP_STATE_PENDING, true)) 181 return 0; 182 183 /* That failed, try via the resend mechanism */ 184 desc = irq_get_desc_buslock(irq, &flags, 0); 185 if (!desc) 186 return -EINVAL; 187 188 /* 189 * Only try to inject when the interrupt is: 190 * - not NMI type 191 * - activated 192 */ 193 if (irq_is_nmi(desc) || !irqd_is_activated(&desc->irq_data)) 194 err = -EINVAL; 195 else 196 err = check_irq_resend(desc, true); 197 198 irq_put_desc_busunlock(desc, flags); 199 return err; 200 } 201 EXPORT_SYMBOL_GPL(irq_inject_interrupt); 202 #endif 203
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.