irq_comm.c 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. * irq_comm.c: Common API for in kernel interrupt controller
  3. * Copyright (c) 2007, Intel Corporation.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms and conditions of the GNU General Public License,
  7. * version 2, as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along with
  15. * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
  16. * Place - Suite 330, Boston, MA 02111-1307 USA.
  17. * Authors:
  18. * Yaozu (Eddie) Dong <Eddie.dong@intel.com>
  19. *
  20. */
  21. #include <linux/kvm_host.h>
  22. #include "irq.h"
  23. #include "ioapic.h"
  24. /* This should be called with the kvm->lock mutex held */
  25. void kvm_set_irq(struct kvm *kvm, int irq_source_id, int irq, int level)
  26. {
  27. unsigned long *irq_state = (unsigned long *)&kvm->arch.irq_states[irq];
  28. /* Logical OR for level trig interrupt */
  29. if (level)
  30. set_bit(irq_source_id, irq_state);
  31. else
  32. clear_bit(irq_source_id, irq_state);
  33. /* Not possible to detect if the guest uses the PIC or the
  34. * IOAPIC. So set the bit in both. The guest will ignore
  35. * writes to the unused one.
  36. */
  37. kvm_ioapic_set_irq(kvm->arch.vioapic, irq, !!(*irq_state));
  38. #ifdef CONFIG_X86
  39. kvm_pic_set_irq(pic_irqchip(kvm), irq, !!(*irq_state));
  40. #endif
  41. }
  42. void kvm_notify_acked_irq(struct kvm *kvm, unsigned gsi)
  43. {
  44. struct kvm_irq_ack_notifier *kian;
  45. struct hlist_node *n;
  46. hlist_for_each_entry(kian, n, &kvm->arch.irq_ack_notifier_list, link)
  47. if (kian->gsi == gsi)
  48. kian->irq_acked(kian);
  49. }
  50. void kvm_register_irq_ack_notifier(struct kvm *kvm,
  51. struct kvm_irq_ack_notifier *kian)
  52. {
  53. hlist_add_head(&kian->link, &kvm->arch.irq_ack_notifier_list);
  54. }
  55. void kvm_unregister_irq_ack_notifier(struct kvm_irq_ack_notifier *kian)
  56. {
  57. if (!kian)
  58. return;
  59. hlist_del(&kian->link);
  60. }
  61. /* The caller must hold kvm->lock mutex */
  62. int kvm_request_irq_source_id(struct kvm *kvm)
  63. {
  64. unsigned long *bitmap = &kvm->arch.irq_sources_bitmap;
  65. int irq_source_id = find_first_zero_bit(bitmap,
  66. sizeof(kvm->arch.irq_sources_bitmap));
  67. if (irq_source_id >= sizeof(kvm->arch.irq_sources_bitmap)) {
  68. printk(KERN_WARNING "kvm: exhaust allocatable IRQ sources!\n");
  69. irq_source_id = -EFAULT;
  70. } else
  71. set_bit(irq_source_id, bitmap);
  72. return irq_source_id;
  73. }
  74. void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id)
  75. {
  76. int i;
  77. if (irq_source_id <= 0 ||
  78. irq_source_id >= sizeof(kvm->arch.irq_sources_bitmap)) {
  79. printk(KERN_ERR "kvm: IRQ source ID out of range!\n");
  80. return;
  81. }
  82. for (i = 0; i < KVM_IOAPIC_NUM_PINS; i++)
  83. clear_bit(irq_source_id, &kvm->arch.irq_states[i]);
  84. clear_bit(irq_source_id, &kvm->arch.irq_sources_bitmap);
  85. }