interrupt.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. /*
  2. * This file is subject to the terms and conditions of the GNU General Public
  3. * License. See the file "COPYING" in the main directory of this archive
  4. * for more details.
  5. *
  6. * KVM/MIPS: Interrupt delivery
  7. *
  8. * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
  9. * Authors: Sanjay Lal <sanjayl@kymasys.com>
  10. */
  11. #include <linux/errno.h>
  12. #include <linux/err.h>
  13. #include <linux/module.h>
  14. #include <linux/vmalloc.h>
  15. #include <linux/fs.h>
  16. #include <linux/bootmem.h>
  17. #include <asm/page.h>
  18. #include <asm/cacheflush.h>
  19. #include <linux/kvm_host.h>
  20. #include "interrupt.h"
  21. void kvm_mips_queue_irq(struct kvm_vcpu *vcpu, uint32_t priority)
  22. {
  23. set_bit(priority, &vcpu->arch.pending_exceptions);
  24. }
  25. void kvm_mips_dequeue_irq(struct kvm_vcpu *vcpu, uint32_t priority)
  26. {
  27. clear_bit(priority, &vcpu->arch.pending_exceptions);
  28. }
  29. void kvm_mips_queue_timer_int_cb(struct kvm_vcpu *vcpu)
  30. {
  31. /*
  32. * Cause bits to reflect the pending timer interrupt,
  33. * the EXC code will be set when we are actually
  34. * delivering the interrupt:
  35. */
  36. kvm_set_c0_guest_cause(vcpu->arch.cop0, (C_IRQ5 | C_TI));
  37. /* Queue up an INT exception for the core */
  38. kvm_mips_queue_irq(vcpu, MIPS_EXC_INT_TIMER);
  39. }
  40. void kvm_mips_dequeue_timer_int_cb(struct kvm_vcpu *vcpu)
  41. {
  42. kvm_clear_c0_guest_cause(vcpu->arch.cop0, (C_IRQ5 | C_TI));
  43. kvm_mips_dequeue_irq(vcpu, MIPS_EXC_INT_TIMER);
  44. }
  45. void kvm_mips_queue_io_int_cb(struct kvm_vcpu *vcpu,
  46. struct kvm_mips_interrupt *irq)
  47. {
  48. int intr = (int)irq->irq;
  49. /*
  50. * Cause bits to reflect the pending IO interrupt,
  51. * the EXC code will be set when we are actually
  52. * delivering the interrupt:
  53. */
  54. switch (intr) {
  55. case 2:
  56. kvm_set_c0_guest_cause(vcpu->arch.cop0, (C_IRQ0));
  57. /* Queue up an INT exception for the core */
  58. kvm_mips_queue_irq(vcpu, MIPS_EXC_INT_IO);
  59. break;
  60. case 3:
  61. kvm_set_c0_guest_cause(vcpu->arch.cop0, (C_IRQ1));
  62. kvm_mips_queue_irq(vcpu, MIPS_EXC_INT_IPI_1);
  63. break;
  64. case 4:
  65. kvm_set_c0_guest_cause(vcpu->arch.cop0, (C_IRQ2));
  66. kvm_mips_queue_irq(vcpu, MIPS_EXC_INT_IPI_2);
  67. break;
  68. default:
  69. break;
  70. }
  71. }
  72. void kvm_mips_dequeue_io_int_cb(struct kvm_vcpu *vcpu,
  73. struct kvm_mips_interrupt *irq)
  74. {
  75. int intr = (int)irq->irq;
  76. switch (intr) {
  77. case -2:
  78. kvm_clear_c0_guest_cause(vcpu->arch.cop0, (C_IRQ0));
  79. kvm_mips_dequeue_irq(vcpu, MIPS_EXC_INT_IO);
  80. break;
  81. case -3:
  82. kvm_clear_c0_guest_cause(vcpu->arch.cop0, (C_IRQ1));
  83. kvm_mips_dequeue_irq(vcpu, MIPS_EXC_INT_IPI_1);
  84. break;
  85. case -4:
  86. kvm_clear_c0_guest_cause(vcpu->arch.cop0, (C_IRQ2));
  87. kvm_mips_dequeue_irq(vcpu, MIPS_EXC_INT_IPI_2);
  88. break;
  89. default:
  90. break;
  91. }
  92. }
  93. /* Deliver the interrupt of the corresponding priority, if possible. */
  94. int kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority,
  95. uint32_t cause)
  96. {
  97. int allowed = 0;
  98. uint32_t exccode;
  99. struct kvm_vcpu_arch *arch = &vcpu->arch;
  100. struct mips_coproc *cop0 = vcpu->arch.cop0;
  101. switch (priority) {
  102. case MIPS_EXC_INT_TIMER:
  103. if ((kvm_read_c0_guest_status(cop0) & ST0_IE)
  104. && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
  105. && (kvm_read_c0_guest_status(cop0) & IE_IRQ5)) {
  106. allowed = 1;
  107. exccode = T_INT;
  108. }
  109. break;
  110. case MIPS_EXC_INT_IO:
  111. if ((kvm_read_c0_guest_status(cop0) & ST0_IE)
  112. && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
  113. && (kvm_read_c0_guest_status(cop0) & IE_IRQ0)) {
  114. allowed = 1;
  115. exccode = T_INT;
  116. }
  117. break;
  118. case MIPS_EXC_INT_IPI_1:
  119. if ((kvm_read_c0_guest_status(cop0) & ST0_IE)
  120. && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
  121. && (kvm_read_c0_guest_status(cop0) & IE_IRQ1)) {
  122. allowed = 1;
  123. exccode = T_INT;
  124. }
  125. break;
  126. case MIPS_EXC_INT_IPI_2:
  127. if ((kvm_read_c0_guest_status(cop0) & ST0_IE)
  128. && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
  129. && (kvm_read_c0_guest_status(cop0) & IE_IRQ2)) {
  130. allowed = 1;
  131. exccode = T_INT;
  132. }
  133. break;
  134. default:
  135. break;
  136. }
  137. /* Are we allowed to deliver the interrupt ??? */
  138. if (allowed) {
  139. if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) {
  140. /* save old pc */
  141. kvm_write_c0_guest_epc(cop0, arch->pc);
  142. kvm_set_c0_guest_status(cop0, ST0_EXL);
  143. if (cause & CAUSEF_BD)
  144. kvm_set_c0_guest_cause(cop0, CAUSEF_BD);
  145. else
  146. kvm_clear_c0_guest_cause(cop0, CAUSEF_BD);
  147. kvm_debug("Delivering INT @ pc %#lx\n", arch->pc);
  148. } else
  149. kvm_err("Trying to deliver interrupt when EXL is already set\n");
  150. kvm_change_c0_guest_cause(cop0, CAUSEF_EXCCODE,
  151. (exccode << CAUSEB_EXCCODE));
  152. /* XXXSL Set PC to the interrupt exception entry point */
  153. if (kvm_read_c0_guest_cause(cop0) & CAUSEF_IV)
  154. arch->pc = KVM_GUEST_KSEG0 + 0x200;
  155. else
  156. arch->pc = KVM_GUEST_KSEG0 + 0x180;
  157. clear_bit(priority, &vcpu->arch.pending_exceptions);
  158. }
  159. return allowed;
  160. }
  161. int kvm_mips_irq_clear_cb(struct kvm_vcpu *vcpu, unsigned int priority,
  162. uint32_t cause)
  163. {
  164. return 1;
  165. }
  166. void kvm_mips_deliver_interrupts(struct kvm_vcpu *vcpu, uint32_t cause)
  167. {
  168. unsigned long *pending = &vcpu->arch.pending_exceptions;
  169. unsigned long *pending_clr = &vcpu->arch.pending_exceptions_clr;
  170. unsigned int priority;
  171. if (!(*pending) && !(*pending_clr))
  172. return;
  173. priority = __ffs(*pending_clr);
  174. while (priority <= MIPS_EXC_MAX) {
  175. if (kvm_mips_callbacks->irq_clear(vcpu, priority, cause)) {
  176. if (!KVM_MIPS_IRQ_CLEAR_ALL_AT_ONCE)
  177. break;
  178. }
  179. priority = find_next_bit(pending_clr,
  180. BITS_PER_BYTE * sizeof(*pending_clr),
  181. priority + 1);
  182. }
  183. priority = __ffs(*pending);
  184. while (priority <= MIPS_EXC_MAX) {
  185. if (kvm_mips_callbacks->irq_deliver(vcpu, priority, cause)) {
  186. if (!KVM_MIPS_IRQ_DELIVER_ALL_AT_ONCE)
  187. break;
  188. }
  189. priority = find_next_bit(pending,
  190. BITS_PER_BYTE * sizeof(*pending),
  191. priority + 1);
  192. }
  193. }
  194. int kvm_mips_pending_timer(struct kvm_vcpu *vcpu)
  195. {
  196. return test_bit(MIPS_EXC_INT_TIMER, &vcpu->arch.pending_exceptions);
  197. }