Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'irq/for-x86' into irq/core

Pull in the branch which can be consumed by x86 to build their changes
on top.

+51
+6
include/linux/irq.h
··· 327 327 * @irq_write_msi_msg: optional to write message content for MSI 328 328 * @irq_get_irqchip_state: return the internal state of an interrupt 329 329 * @irq_set_irqchip_state: set the internal state of a interrupt 330 + * @irq_set_vcpu_affinity: optional to target a vCPU in a virtual machine 330 331 * @flags: chip specific flags 331 332 */ 332 333 struct irq_chip { ··· 369 368 370 369 int (*irq_get_irqchip_state)(struct irq_data *data, enum irqchip_irq_state which, bool *state); 371 370 int (*irq_set_irqchip_state)(struct irq_data *data, enum irqchip_irq_state which, bool state); 371 + 372 + int (*irq_set_vcpu_affinity)(struct irq_data *data, void *vcpu_info); 372 373 373 374 unsigned long flags; 374 375 }; ··· 425 422 extern void irq_cpu_offline(void); 426 423 extern int irq_set_affinity_locked(struct irq_data *data, 427 424 const struct cpumask *cpumask, bool force); 425 + extern int irq_set_vcpu_affinity(unsigned int irq, void *vcpu_info); 428 426 429 427 #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_PENDING_IRQ) 430 428 void irq_move_irq(struct irq_data *data); ··· 473 469 const struct cpumask *dest, 474 470 bool force); 475 471 extern int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on); 472 + extern int irq_chip_set_vcpu_affinity_parent(struct irq_data *data, 473 + void *vcpu_info); 476 474 #endif 477 475 478 476 /* Handling of unhandled and spurious interrupts: */
+14
kernel/irq/chip.c
··· 978 978 } 979 979 980 980 /** 981 + * irq_chip_set_vcpu_affinity_parent - Set vcpu affinity on the parent interrupt 982 + * @data: Pointer to interrupt specific data 983 + * @dest: The vcpu affinity information 984 + */ 985 + int irq_chip_set_vcpu_affinity_parent(struct irq_data *data, void *vcpu_info) 986 + { 987 + data = data->parent_data; 988 + if (data->chip->irq_set_vcpu_affinity) 989 + return data->chip->irq_set_vcpu_affinity(data, vcpu_info); 990 + 991 + return -ENOSYS; 992 + } 993 + 994 + /** 981 995 * irq_chip_set_wake_parent - Set/reset wake-up on the parent interrupt 982 996 * @data: Pointer to interrupt specific data 983 997 * @on: Whether to set or reset the wake-up capability of this irq
+31
kernel/irq/manage.c
··· 256 256 } 257 257 EXPORT_SYMBOL_GPL(irq_set_affinity_hint); 258 258 259 + /** 260 + * irq_set_vcpu_affinity - Set vcpu affinity for the interrupt 261 + * @irq: interrupt number to set affinity 262 + * @vcpu_info: vCPU specific data 263 + * 264 + * This function uses the vCPU specific data to set the vCPU 265 + * affinity for an irq. The vCPU specific data is passed from 266 + * outside, such as KVM. One example code path is as below: 267 + * KVM -> IOMMU -> irq_set_vcpu_affinity(). 268 + */ 269 + int irq_set_vcpu_affinity(unsigned int irq, void *vcpu_info) 270 + { 271 + unsigned long flags; 272 + struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0); 273 + struct irq_data *data; 274 + struct irq_chip *chip; 275 + int ret = -ENOSYS; 276 + 277 + if (!desc) 278 + return -EINVAL; 279 + 280 + data = irq_desc_get_irq_data(desc); 281 + chip = irq_data_get_irq_chip(data); 282 + if (chip && chip->irq_set_vcpu_affinity) 283 + ret = chip->irq_set_vcpu_affinity(data, vcpu_info); 284 + irq_put_desc_unlock(desc, flags); 285 + 286 + return ret; 287 + } 288 + EXPORT_SYMBOL_GPL(irq_set_vcpu_affinity); 289 + 259 290 static void irq_affinity_notify(struct work_struct *work) 260 291 { 261 292 struct irq_affinity_notify *notify =