diff options
| -rw-r--r-- | arch/x86/pci/vmd.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/arch/x86/pci/vmd.c b/arch/x86/pci/vmd.c index b814ca675131..7948be342ee9 100644 --- a/arch/x86/pci/vmd.c +++ b/arch/x86/pci/vmd.c | |||
| @@ -41,6 +41,7 @@ static DEFINE_RAW_SPINLOCK(list_lock); | |||
| 41 | * @node: list item for parent traversal. | 41 | * @node: list item for parent traversal. |
| 42 | * @rcu: RCU callback item for freeing. | 42 | * @rcu: RCU callback item for freeing. |
| 43 | * @irq: back pointer to parent. | 43 | * @irq: back pointer to parent. |
| 44 | * @enabled: true if driver enabled IRQ | ||
| 44 | * @virq: the virtual IRQ value provided to the requesting driver. | 45 | * @virq: the virtual IRQ value provided to the requesting driver. |
| 45 | * | 46 | * |
| 46 | * Every MSI/MSI-X IRQ requested for a device in a VMD domain will be mapped to | 47 | * Every MSI/MSI-X IRQ requested for a device in a VMD domain will be mapped to |
| @@ -50,6 +51,7 @@ struct vmd_irq { | |||
| 50 | struct list_head node; | 51 | struct list_head node; |
| 51 | struct rcu_head rcu; | 52 | struct rcu_head rcu; |
| 52 | struct vmd_irq_list *irq; | 53 | struct vmd_irq_list *irq; |
| 54 | bool enabled; | ||
| 53 | unsigned int virq; | 55 | unsigned int virq; |
| 54 | }; | 56 | }; |
| 55 | 57 | ||
| @@ -122,7 +124,9 @@ static void vmd_irq_enable(struct irq_data *data) | |||
| 122 | unsigned long flags; | 124 | unsigned long flags; |
| 123 | 125 | ||
| 124 | raw_spin_lock_irqsave(&list_lock, flags); | 126 | raw_spin_lock_irqsave(&list_lock, flags); |
| 127 | WARN_ON(vmdirq->enabled); | ||
| 125 | list_add_tail_rcu(&vmdirq->node, &vmdirq->irq->irq_list); | 128 | list_add_tail_rcu(&vmdirq->node, &vmdirq->irq->irq_list); |
| 129 | vmdirq->enabled = true; | ||
| 126 | raw_spin_unlock_irqrestore(&list_lock, flags); | 130 | raw_spin_unlock_irqrestore(&list_lock, flags); |
| 127 | 131 | ||
| 128 | data->chip->irq_unmask(data); | 132 | data->chip->irq_unmask(data); |
| @@ -136,8 +140,10 @@ static void vmd_irq_disable(struct irq_data *data) | |||
| 136 | data->chip->irq_mask(data); | 140 | data->chip->irq_mask(data); |
| 137 | 141 | ||
| 138 | raw_spin_lock_irqsave(&list_lock, flags); | 142 | raw_spin_lock_irqsave(&list_lock, flags); |
| 139 | list_del_rcu(&vmdirq->node); | 143 | if (vmdirq->enabled) { |
| 140 | INIT_LIST_HEAD_RCU(&vmdirq->node); | 144 | list_del_rcu(&vmdirq->node); |
| 145 | vmdirq->enabled = false; | ||
| 146 | } | ||
| 141 | raw_spin_unlock_irqrestore(&list_lock, flags); | 147 | raw_spin_unlock_irqrestore(&list_lock, flags); |
| 142 | } | 148 | } |
| 143 | 149 | ||
