aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2013-04-12 10:08:47 -0400
committerAlexander Graf <agraf@suse.de>2013-04-26 14:27:24 -0400
commiteb1e4f43e0f47f2655372c7d32c43db9711c278e (patch)
treeac084d48a5590f6ca712242e0ca139abf57250a5 /arch
parent5df554ad5b7522ea62b0ff9d5be35183494efc21 (diff)
kvm/ppc/mpic: add KVM_CAP_IRQ_MPIC
Enabling this capability connects the vcpu to the designated in-kernel MPIC. Using explicit connections between vcpus and irqchips allows for flexibility, but the main benefit at the moment is that it simplifies the code -- KVM doesn't need vm-global state to remember which MPIC object is associated with this vm, and it doesn't need to care about ordering between irqchip creation and vcpu creation. Signed-off-by: Scott Wood <scottwood@freescale.com> [agraf: add stub functions for kvmppc_mpic_{dis,}connect_vcpu] Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/include/asm/kvm_host.h9
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h15
-rw-r--r--arch/powerpc/kvm/booke.c4
-rw-r--r--arch/powerpc/kvm/mpic.c82
-rw-r--r--arch/powerpc/kvm/powerpc.c30
5 files changed, 132 insertions, 8 deletions
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 153c8c2b0f88..c3f8ceffa412 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -377,6 +377,11 @@ struct kvmppc_booke_debug_reg {
377 u64 dac[KVMPPC_BOOKE_MAX_DAC]; 377 u64 dac[KVMPPC_BOOKE_MAX_DAC];
378}; 378};
379 379
380#define KVMPPC_IRQ_DEFAULT 0
381#define KVMPPC_IRQ_MPIC 1
382
383struct openpic;
384
380struct kvm_vcpu_arch { 385struct kvm_vcpu_arch {
381 ulong host_stack; 386 ulong host_stack;
382 u32 host_pid; 387 u32 host_pid;
@@ -558,6 +563,10 @@ struct kvm_vcpu_arch {
558 unsigned long magic_page_pa; /* phys addr to map the magic page to */ 563 unsigned long magic_page_pa; /* phys addr to map the magic page to */
559 unsigned long magic_page_ea; /* effect. addr to map the magic page to */ 564 unsigned long magic_page_ea; /* effect. addr to map the magic page to */
560 565
566 int irq_type; /* one of KVM_IRQ_* */
567 int irq_cpu_id;
568 struct openpic *mpic; /* KVM_IRQ_MPIC */
569
561#ifdef CONFIG_KVM_BOOK3S_64_HV 570#ifdef CONFIG_KVM_BOOK3S_64_HV
562 struct kvm_vcpu_arch_shared shregs; 571 struct kvm_vcpu_arch_shared shregs;
563 572
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 3810f9c7616c..df9c80b37905 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -248,7 +248,6 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *);
248void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid); 248void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid);
249 249
250struct openpic; 250struct openpic;
251void kvmppc_mpic_put(struct openpic *opp);
252 251
253#ifdef CONFIG_KVM_BOOK3S_64_HV 252#ifdef CONFIG_KVM_BOOK3S_64_HV
254static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr) 253static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr)
@@ -278,6 +277,9 @@ static inline void kvmppc_set_epr(struct kvm_vcpu *vcpu, u32 epr)
278#ifdef CONFIG_KVM_MPIC 277#ifdef CONFIG_KVM_MPIC
279 278
280void kvmppc_mpic_set_epr(struct kvm_vcpu *vcpu); 279void kvmppc_mpic_set_epr(struct kvm_vcpu *vcpu);
280int kvmppc_mpic_connect_vcpu(struct kvm_device *dev, struct kvm_vcpu *vcpu,
281 u32 cpu);
282void kvmppc_mpic_disconnect_vcpu(struct openpic *opp, struct kvm_vcpu *vcpu);
281 283
282#else 284#else
283 285
@@ -285,6 +287,17 @@ static inline void kvmppc_mpic_set_epr(struct kvm_vcpu *vcpu)
285{ 287{
286} 288}
287 289
290static inline int kvmppc_mpic_connect_vcpu(struct kvm_device *dev,
291 struct kvm_vcpu *vcpu, u32 cpu)
292{
293 return -EINVAL;
294}
295
296static inline void kvmppc_mpic_disconnect_vcpu(struct openpic *opp,
297 struct kvm_vcpu *vcpu)
298{
299}
300
288#endif /* CONFIG_KVM_MPIC */ 301#endif /* CONFIG_KVM_MPIC */
289 302
290int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu, 303int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu,
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 4da11ed48c59..1020119226db 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -430,6 +430,10 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
430 if (update_epr == true) { 430 if (update_epr == true) {
431 if (vcpu->arch.epr_flags & KVMPPC_EPR_USER) 431 if (vcpu->arch.epr_flags & KVMPPC_EPR_USER)
432 kvm_make_request(KVM_REQ_EPR_EXIT, vcpu); 432 kvm_make_request(KVM_REQ_EPR_EXIT, vcpu);
433 else if (vcpu->arch.epr_flags & KVMPPC_EPR_KERNEL) {
434 BUG_ON(vcpu->arch.irq_type != KVMPPC_IRQ_MPIC);
435 kvmppc_mpic_set_epr(vcpu);
436 }
433 } 437 }
434 438
435 new_msr &= msr_mask; 439 new_msr &= msr_mask;
diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c
index cb451b91e342..10bc08a246fd 100644
--- a/arch/powerpc/kvm/mpic.c
+++ b/arch/powerpc/kvm/mpic.c
@@ -115,7 +115,7 @@ static int get_current_cpu(void)
115{ 115{
116#if defined(CONFIG_KVM) && defined(CONFIG_BOOKE) 116#if defined(CONFIG_KVM) && defined(CONFIG_BOOKE)
117 struct kvm_vcpu *vcpu = current->thread.kvm_vcpu; 117 struct kvm_vcpu *vcpu = current->thread.kvm_vcpu;
118 return vcpu ? vcpu->vcpu_id : -1; 118 return vcpu ? vcpu->arch.irq_cpu_id : -1;
119#else 119#else
120 /* XXX */ 120 /* XXX */
121 return -1; 121 return -1;
@@ -249,7 +249,7 @@ static void mpic_irq_raise(struct openpic *opp, struct irq_dest *dst,
249 return; 249 return;
250 } 250 }
251 251
252 pr_debug("%s: cpu %d output %d\n", __func__, dst->vcpu->vcpu_id, 252 pr_debug("%s: cpu %d output %d\n", __func__, dst->vcpu->arch.irq_cpu_id,
253 output); 253 output);
254 254
255 if (output != ILR_INTTGT_INT) /* TODO */ 255 if (output != ILR_INTTGT_INT) /* TODO */
@@ -267,7 +267,7 @@ static void mpic_irq_lower(struct openpic *opp, struct irq_dest *dst,
267 return; 267 return;
268 } 268 }
269 269
270 pr_debug("%s: cpu %d output %d\n", __func__, dst->vcpu->vcpu_id, 270 pr_debug("%s: cpu %d output %d\n", __func__, dst->vcpu->arch.irq_cpu_id,
271 output); 271 output);
272 272
273 if (output != ILR_INTTGT_INT) /* TODO */ 273 if (output != ILR_INTTGT_INT) /* TODO */
@@ -1165,6 +1165,20 @@ static uint32_t openpic_iack(struct openpic *opp, struct irq_dest *dst,
1165 return retval; 1165 return retval;
1166} 1166}
1167 1167
1168void kvmppc_mpic_set_epr(struct kvm_vcpu *vcpu)
1169{
1170 struct openpic *opp = vcpu->arch.mpic;
1171 int cpu = vcpu->arch.irq_cpu_id;
1172 unsigned long flags;
1173
1174 spin_lock_irqsave(&opp->lock, flags);
1175
1176 if ((opp->gcr & opp->mpic_mode_mask) == GCR_MODE_PROXY)
1177 kvmppc_set_epr(vcpu, openpic_iack(opp, &opp->dst[cpu], cpu));
1178
1179 spin_unlock_irqrestore(&opp->lock, flags);
1180}
1181
1168static int openpic_cpu_read_internal(void *opaque, gpa_t addr, 1182static int openpic_cpu_read_internal(void *opaque, gpa_t addr,
1169 u32 *ptr, int idx) 1183 u32 *ptr, int idx)
1170{ 1184{
@@ -1431,10 +1445,10 @@ static void map_mmio(struct openpic *opp)
1431 1445
1432static void unmap_mmio(struct openpic *opp) 1446static void unmap_mmio(struct openpic *opp)
1433{ 1447{
1434 BUG_ON(opp->mmio_mapped); 1448 if (opp->mmio_mapped) {
1435 opp->mmio_mapped = false; 1449 opp->mmio_mapped = false;
1436 1450 kvm_io_bus_unregister_dev(opp->kvm, KVM_MMIO_BUS, &opp->mmio);
1437 kvm_io_bus_unregister_dev(opp->kvm, KVM_MMIO_BUS, &opp->mmio); 1451 }
1438} 1452}
1439 1453
1440static int set_base_addr(struct openpic *opp, struct kvm_device_attr *attr) 1454static int set_base_addr(struct openpic *opp, struct kvm_device_attr *attr)
@@ -1693,3 +1707,57 @@ struct kvm_device_ops kvm_mpic_ops = {
1693 .get_attr = mpic_get_attr, 1707 .get_attr = mpic_get_attr,
1694 .has_attr = mpic_has_attr, 1708 .has_attr = mpic_has_attr,
1695}; 1709};
1710
1711int kvmppc_mpic_connect_vcpu(struct kvm_device *dev, struct kvm_vcpu *vcpu,
1712 u32 cpu)
1713{
1714 struct openpic *opp = dev->private;
1715 int ret = 0;
1716
1717 if (dev->ops != &kvm_mpic_ops)
1718 return -EPERM;
1719 if (opp->kvm != vcpu->kvm)
1720 return -EPERM;
1721 if (cpu < 0 || cpu >= MAX_CPU)
1722 return -EPERM;
1723
1724 spin_lock_irq(&opp->lock);
1725
1726 if (opp->dst[cpu].vcpu) {
1727 ret = -EEXIST;
1728 goto out;
1729 }
1730 if (vcpu->arch.irq_type) {
1731 ret = -EBUSY;
1732 goto out;
1733 }
1734
1735 opp->dst[cpu].vcpu = vcpu;
1736 opp->nb_cpus = max(opp->nb_cpus, cpu + 1);
1737
1738 vcpu->arch.mpic = opp;
1739 vcpu->arch.irq_cpu_id = cpu;
1740 vcpu->arch.irq_type = KVMPPC_IRQ_MPIC;
1741
1742 /* This might need to be changed if GCR gets extended */
1743 if (opp->mpic_mode_mask == GCR_MODE_PROXY)
1744 vcpu->arch.epr_flags |= KVMPPC_EPR_KERNEL;
1745
1746 kvm_device_get(dev);
1747out:
1748 spin_unlock_irq(&opp->lock);
1749 return ret;
1750}
1751
1752/*
1753 * This should only happen immediately before the mpic is destroyed,
1754 * so we shouldn't need to worry about anything still trying to
1755 * access the vcpu pointer.
1756 */
1757void kvmppc_mpic_disconnect_vcpu(struct openpic *opp, struct kvm_vcpu *vcpu)
1758{
1759 BUG_ON(!opp->dst[vcpu->arch.irq_cpu_id].vcpu);
1760
1761 opp->dst[vcpu->arch.irq_cpu_id].vcpu = NULL;
1762 kvm_device_put(opp->dev);
1763}
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 88d69cf1f953..5d046bbdf11f 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -25,6 +25,7 @@
25#include <linux/hrtimer.h> 25#include <linux/hrtimer.h>
26#include <linux/fs.h> 26#include <linux/fs.h>
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/file.h>
28#include <asm/cputable.h> 29#include <asm/cputable.h>
29#include <asm/uaccess.h> 30#include <asm/uaccess.h>
30#include <asm/kvm_ppc.h> 31#include <asm/kvm_ppc.h>
@@ -327,6 +328,9 @@ int kvm_dev_ioctl_check_extension(long ext)
327#if defined(CONFIG_KVM_E500V2) || defined(CONFIG_KVM_E500MC) 328#if defined(CONFIG_KVM_E500V2) || defined(CONFIG_KVM_E500MC)
328 case KVM_CAP_SW_TLB: 329 case KVM_CAP_SW_TLB:
329#endif 330#endif
331#ifdef CONFIG_KVM_MPIC
332 case KVM_CAP_IRQ_MPIC:
333#endif
330 r = 1; 334 r = 1;
331 break; 335 break;
332 case KVM_CAP_COALESCED_MMIO: 336 case KVM_CAP_COALESCED_MMIO:
@@ -460,6 +464,13 @@ void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
460 tasklet_kill(&vcpu->arch.tasklet); 464 tasklet_kill(&vcpu->arch.tasklet);
461 465
462 kvmppc_remove_vcpu_debugfs(vcpu); 466 kvmppc_remove_vcpu_debugfs(vcpu);
467
468 switch (vcpu->arch.irq_type) {
469 case KVMPPC_IRQ_MPIC:
470 kvmppc_mpic_disconnect_vcpu(vcpu->arch.mpic, vcpu);
471 break;
472 }
473
463 kvmppc_core_vcpu_free(vcpu); 474 kvmppc_core_vcpu_free(vcpu);
464} 475}
465 476
@@ -787,6 +798,25 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
787 break; 798 break;
788 } 799 }
789#endif 800#endif
801#ifdef CONFIG_KVM_MPIC
802 case KVM_CAP_IRQ_MPIC: {
803 struct file *filp;
804 struct kvm_device *dev;
805
806 r = -EBADF;
807 filp = fget(cap->args[0]);
808 if (!filp)
809 break;
810
811 r = -EPERM;
812 dev = kvm_device_from_filp(filp);
813 if (dev)
814 r = kvmppc_mpic_connect_vcpu(dev, vcpu, cap->args[1]);
815
816 fput(filp);
817 break;
818 }
819#endif
790 default: 820 default:
791 r = -EINVAL; 821 r = -EINVAL;
792 break; 822 break;