aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2014-06-30 06:51:14 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2014-08-05 08:26:33 -0400
commit25a2150bee00b4d996487552948b9b3ba21d0257 (patch)
tree871ddff4f28387cd9c85ade7860c883da3660fbf /arch
parent297e21053a52f060944e9f0de4c64fad9bcd72fc (diff)
KVM: PPC: Enable IRQFD support for the XICS interrupt controller
This makes it possible to use IRQFDs on platforms that use the XICS interrupt controller. To do this we implement kvm_irq_map_gsi() and kvm_irq_map_chip_pin() in book3s_xics.c, so as to provide a 1-1 mapping between global interrupt numbers and XICS interrupt source numbers. For now, all interrupts are mapped as "IRQCHIP" interrupts, and no MSI support is provided. This means that kvm_set_irq can now get called with level == 0 or 1 as well as the powerpc-specific values KVM_INTERRUPT_SET, KVM_INTERRUPT_UNSET and KVM_INTERRUPT_SET_LEVEL. We change ics_deliver_irq() to accept all those values, and remove its report_status argument, as it is always false, given that we don't support KVM_IRQ_LINE_STATUS. This also adds support for interrupt ack notifiers to the XICS code so that the IRQFD resampler functionality can be supported. Signed-off-by: Paul Mackerras <paulus@samba.org> Tested-by: Eric Auger <eric.auger@linaro.org> Tested-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/kvm/Kconfig2
-rw-r--r--arch/powerpc/kvm/book3s_hv_rm_xics.c5
-rw-r--r--arch/powerpc/kvm/book3s_xics.c55
-rw-r--r--arch/powerpc/kvm/book3s_xics.h2
4 files changed, 55 insertions, 9 deletions
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
index d4741dba91af..602eb51d20bc 100644
--- a/arch/powerpc/kvm/Kconfig
+++ b/arch/powerpc/kvm/Kconfig
@@ -170,6 +170,8 @@ config KVM_MPIC
170config KVM_XICS 170config KVM_XICS
171 bool "KVM in-kernel XICS emulation" 171 bool "KVM in-kernel XICS emulation"
172 depends on KVM_BOOK3S_64 && !KVM_MPIC 172 depends on KVM_BOOK3S_64 && !KVM_MPIC
173 select HAVE_KVM_IRQCHIP
174 select HAVE_KVM_IRQFD
173 ---help--- 175 ---help---
174 Include support for the XICS (eXternal Interrupt Controller 176 Include support for the XICS (eXternal Interrupt Controller
175 Specification) interrupt controller architecture used on 177 Specification) interrupt controller architecture used on
diff --git a/arch/powerpc/kvm/book3s_hv_rm_xics.c b/arch/powerpc/kvm/book3s_hv_rm_xics.c
index b4b0082f761c..3ee38e6e884f 100644
--- a/arch/powerpc/kvm/book3s_hv_rm_xics.c
+++ b/arch/powerpc/kvm/book3s_hv_rm_xics.c
@@ -401,6 +401,11 @@ int kvmppc_rm_h_eoi(struct kvm_vcpu *vcpu, unsigned long xirr)
401 icp->rm_action |= XICS_RM_REJECT; 401 icp->rm_action |= XICS_RM_REJECT;
402 icp->rm_reject = irq; 402 icp->rm_reject = irq;
403 } 403 }
404
405 if (!hlist_empty(&vcpu->kvm->irq_ack_notifier_list)) {
406 icp->rm_action |= XICS_RM_NOTIFY_EOI;
407 icp->rm_eoied_irq = irq;
408 }
404 bail: 409 bail:
405 return check_too_hard(xics, icp); 410 return check_too_hard(xics, icp);
406} 411}
diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c
index d1acd32a64c0..eaeb78047fb8 100644
--- a/arch/powerpc/kvm/book3s_xics.c
+++ b/arch/powerpc/kvm/book3s_xics.c
@@ -64,8 +64,12 @@
64static void icp_deliver_irq(struct kvmppc_xics *xics, struct kvmppc_icp *icp, 64static void icp_deliver_irq(struct kvmppc_xics *xics, struct kvmppc_icp *icp,
65 u32 new_irq); 65 u32 new_irq);
66 66
67static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level, 67/*
68 bool report_status) 68 * Return value ideally indicates how the interrupt was handled, but no
69 * callers look at it (given that we don't implement KVM_IRQ_LINE_STATUS),
70 * so just return 0.
71 */
72static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level)
69{ 73{
70 struct ics_irq_state *state; 74 struct ics_irq_state *state;
71 struct kvmppc_ics *ics; 75 struct kvmppc_ics *ics;
@@ -82,17 +86,14 @@ static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level,
82 if (!state->exists) 86 if (!state->exists)
83 return -EINVAL; 87 return -EINVAL;
84 88
85 if (report_status)
86 return state->asserted;
87
88 /* 89 /*
89 * We set state->asserted locklessly. This should be fine as 90 * We set state->asserted locklessly. This should be fine as
90 * we are the only setter, thus concurrent access is undefined 91 * we are the only setter, thus concurrent access is undefined
91 * to begin with. 92 * to begin with.
92 */ 93 */
93 if (level == KVM_INTERRUPT_SET_LEVEL) 94 if (level == 1 || level == KVM_INTERRUPT_SET_LEVEL)
94 state->asserted = 1; 95 state->asserted = 1;
95 else if (level == KVM_INTERRUPT_UNSET) { 96 else if (level == 0 || level == KVM_INTERRUPT_UNSET) {
96 state->asserted = 0; 97 state->asserted = 0;
97 return 0; 98 return 0;
98 } 99 }
@@ -100,7 +101,7 @@ static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level,
100 /* Attempt delivery */ 101 /* Attempt delivery */
101 icp_deliver_irq(xics, NULL, irq); 102 icp_deliver_irq(xics, NULL, irq);
102 103
103 return state->asserted; 104 return 0;
104} 105}
105 106
106static void ics_check_resend(struct kvmppc_xics *xics, struct kvmppc_ics *ics, 107static void ics_check_resend(struct kvmppc_xics *xics, struct kvmppc_ics *ics,
@@ -772,6 +773,8 @@ static noinline int kvmppc_h_eoi(struct kvm_vcpu *vcpu, unsigned long xirr)
772 if (state->asserted) 773 if (state->asserted)
773 icp_deliver_irq(xics, icp, irq); 774 icp_deliver_irq(xics, icp, irq);
774 775
776 kvm_notify_acked_irq(vcpu->kvm, 0, irq);
777
775 return H_SUCCESS; 778 return H_SUCCESS;
776} 779}
777 780
@@ -789,6 +792,8 @@ static noinline int kvmppc_xics_rm_complete(struct kvm_vcpu *vcpu, u32 hcall)
789 icp_check_resend(xics, icp); 792 icp_check_resend(xics, icp);
790 if (icp->rm_action & XICS_RM_REJECT) 793 if (icp->rm_action & XICS_RM_REJECT)
791 icp_deliver_irq(xics, icp, icp->rm_reject); 794 icp_deliver_irq(xics, icp, icp->rm_reject);
795 if (icp->rm_action & XICS_RM_NOTIFY_EOI)
796 kvm_notify_acked_irq(vcpu->kvm, 0, icp->rm_eoied_irq);
792 797
793 icp->rm_action = 0; 798 icp->rm_action = 0;
794 799
@@ -1170,7 +1175,16 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level,
1170{ 1175{
1171 struct kvmppc_xics *xics = kvm->arch.xics; 1176 struct kvmppc_xics *xics = kvm->arch.xics;
1172 1177
1173 return ics_deliver_irq(xics, irq, level, line_status); 1178 return ics_deliver_irq(xics, irq, level);
1179}
1180
1181int kvm_set_msi(struct kvm_kernel_irq_routing_entry *irq_entry, struct kvm *kvm,
1182 int irq_source_id, int level, bool line_status)
1183{
1184 if (!level)
1185 return -1;
1186 return kvm_set_irq(kvm, irq_source_id, irq_entry->gsi,
1187 level, line_status);
1174} 1188}
1175 1189
1176static int xics_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) 1190static int xics_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
@@ -1301,3 +1315,26 @@ void kvmppc_xics_free_icp(struct kvm_vcpu *vcpu)
1301 vcpu->arch.icp = NULL; 1315 vcpu->arch.icp = NULL;
1302 vcpu->arch.irq_type = KVMPPC_IRQ_DEFAULT; 1316 vcpu->arch.irq_type = KVMPPC_IRQ_DEFAULT;
1303} 1317}
1318
1319static int xics_set_irq(struct kvm_kernel_irq_routing_entry *e,
1320 struct kvm *kvm, int irq_source_id, int level,
1321 bool line_status)
1322{
1323 return kvm_set_irq(kvm, irq_source_id, e->gsi, level, line_status);
1324}
1325
1326int kvm_irq_map_gsi(struct kvm *kvm,
1327 struct kvm_kernel_irq_routing_entry *entries, int gsi)
1328{
1329 entries->gsi = gsi;
1330 entries->type = KVM_IRQ_ROUTING_IRQCHIP;
1331 entries->set = xics_set_irq;
1332 entries->irqchip.irqchip = 0;
1333 entries->irqchip.pin = gsi;
1334 return 1;
1335}
1336
1337int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin)
1338{
1339 return pin;
1340}
diff --git a/arch/powerpc/kvm/book3s_xics.h b/arch/powerpc/kvm/book3s_xics.h
index dd9326c5c19b..e8aaa7a3f209 100644
--- a/arch/powerpc/kvm/book3s_xics.h
+++ b/arch/powerpc/kvm/book3s_xics.h
@@ -71,9 +71,11 @@ struct kvmppc_icp {
71#define XICS_RM_KICK_VCPU 0x1 71#define XICS_RM_KICK_VCPU 0x1
72#define XICS_RM_CHECK_RESEND 0x2 72#define XICS_RM_CHECK_RESEND 0x2
73#define XICS_RM_REJECT 0x4 73#define XICS_RM_REJECT 0x4
74#define XICS_RM_NOTIFY_EOI 0x8
74 u32 rm_action; 75 u32 rm_action;
75 struct kvm_vcpu *rm_kick_target; 76 struct kvm_vcpu *rm_kick_target;
76 u32 rm_reject; 77 u32 rm_reject;
78 u32 rm_eoied_irq;
77 79
78 /* Debug stuff for real mode */ 80 /* Debug stuff for real mode */
79 union kvmppc_icp_state rm_dbgstate; 81 union kvmppc_icp_state rm_dbgstate;