aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/include/asm/kvm_host.h7
-rw-r--r--arch/powerpc/include/uapi/asm/kvm.h1
-rw-r--r--arch/powerpc/kvm/Kconfig3
-rw-r--r--arch/powerpc/kvm/Makefile1
-rw-r--r--arch/powerpc/kvm/irq.h17
-rw-r--r--arch/powerpc/kvm/mpic.c111
6 files changed, 139 insertions, 1 deletions
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index c3f8ceffa412..13740a645a6d 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -44,6 +44,10 @@
44#define KVM_COALESCED_MMIO_PAGE_OFFSET 1 44#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
45#endif 45#endif
46 46
47/* These values are internal and can be increased later */
48#define KVM_NR_IRQCHIPS 1
49#define KVM_IRQCHIP_NUM_PINS 256
50
47#if !defined(CONFIG_KVM_440) 51#if !defined(CONFIG_KVM_440)
48#include <linux/mmu_notifier.h> 52#include <linux/mmu_notifier.h>
49 53
@@ -256,6 +260,9 @@ struct kvm_arch {
256#ifdef CONFIG_PPC_BOOK3S_64 260#ifdef CONFIG_PPC_BOOK3S_64
257 struct list_head spapr_tce_tables; 261 struct list_head spapr_tce_tables;
258#endif 262#endif
263#ifdef CONFIG_KVM_MPIC
264 struct openpic *mpic;
265#endif
259}; 266};
260 267
261/* 268/*
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index 02ad96606860..ca871067a69b 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -25,6 +25,7 @@
25/* Select powerpc specific features in <linux/kvm.h> */ 25/* Select powerpc specific features in <linux/kvm.h> */
26#define __KVM_HAVE_SPAPR_TCE 26#define __KVM_HAVE_SPAPR_TCE
27#define __KVM_HAVE_PPC_SMT 27#define __KVM_HAVE_PPC_SMT
28#define __KVM_HAVE_IRQCHIP
28 29
29struct kvm_regs { 30struct kvm_regs {
30 __u64 pc; 31 __u64 pc;
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
index f47e95e0b6de..4bf10b520765 100644
--- a/arch/powerpc/kvm/Kconfig
+++ b/arch/powerpc/kvm/Kconfig
@@ -154,6 +154,9 @@ config KVM_E500MC
154config KVM_MPIC 154config KVM_MPIC
155 bool "KVM in-kernel MPIC emulation" 155 bool "KVM in-kernel MPIC emulation"
156 depends on KVM 156 depends on KVM
157 select HAVE_KVM_IRQCHIP
158 select HAVE_KVM_IRQ_ROUTING
159 select HAVE_KVM_MSI
157 help 160 help
158 Enable support for emulating MPIC devices inside the 161 Enable support for emulating MPIC devices inside the
159 host kernel, rather than relying on userspace to emulate. 162 host kernel, rather than relying on userspace to emulate.
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile
index 4a2277a221bb..4eada0c01082 100644
--- a/arch/powerpc/kvm/Makefile
+++ b/arch/powerpc/kvm/Makefile
@@ -104,6 +104,7 @@ kvm-book3s_32-objs := \
104kvm-objs-$(CONFIG_KVM_BOOK3S_32) := $(kvm-book3s_32-objs) 104kvm-objs-$(CONFIG_KVM_BOOK3S_32) := $(kvm-book3s_32-objs)
105 105
106kvm-objs-$(CONFIG_KVM_MPIC) += mpic.o 106kvm-objs-$(CONFIG_KVM_MPIC) += mpic.o
107kvm-objs-$(CONFIG_HAVE_KVM_IRQ_ROUTING) += $(addprefix ../../../virt/kvm/, irqchip.o)
107 108
108kvm-objs := $(kvm-objs-m) $(kvm-objs-y) 109kvm-objs := $(kvm-objs-m) $(kvm-objs-y)
109 110
diff --git a/arch/powerpc/kvm/irq.h b/arch/powerpc/kvm/irq.h
new file mode 100644
index 000000000000..f1e27fdc8c2e
--- /dev/null
+++ b/arch/powerpc/kvm/irq.h
@@ -0,0 +1,17 @@
1#ifndef __IRQ_H
2#define __IRQ_H
3
4#include <linux/kvm_host.h>
5
6static inline int irqchip_in_kernel(struct kvm *kvm)
7{
8 int ret = 0;
9
10#ifdef CONFIG_KVM_MPIC
11 ret = ret || (kvm->arch.mpic != NULL);
12#endif
13 smp_rmb();
14 return ret;
15}
16
17#endif
diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c
index 10bc08a246fd..89fe1d66a7fb 100644
--- a/arch/powerpc/kvm/mpic.c
+++ b/arch/powerpc/kvm/mpic.c
@@ -1076,7 +1076,9 @@ static int openpic_cpu_write_internal(void *opaque, gpa_t addr,
1076 case 0xA0: /* IACK */ 1076 case 0xA0: /* IACK */
1077 /* Read-only register */ 1077 /* Read-only register */
1078 break; 1078 break;
1079 case 0xB0: /* EOI */ 1079 case 0xB0: { /* EOI */
1080 int notify_eoi;
1081
1080 pr_debug("EOI\n"); 1082 pr_debug("EOI\n");
1081 s_IRQ = IRQ_get_next(opp, &dst->servicing); 1083 s_IRQ = IRQ_get_next(opp, &dst->servicing);
1082 1084
@@ -1087,6 +1089,8 @@ static int openpic_cpu_write_internal(void *opaque, gpa_t addr,
1087 } 1089 }
1088 1090
1089 IRQ_resetbit(&dst->servicing, s_IRQ); 1091 IRQ_resetbit(&dst->servicing, s_IRQ);
1092 /* Notify listeners that the IRQ is over */
1093 notify_eoi = s_IRQ;
1090 /* Set up next servicing IRQ */ 1094 /* Set up next servicing IRQ */
1091 s_IRQ = IRQ_get_next(opp, &dst->servicing); 1095 s_IRQ = IRQ_get_next(opp, &dst->servicing);
1092 /* Check queued interrupts. */ 1096 /* Check queued interrupts. */
@@ -1099,7 +1103,13 @@ static int openpic_cpu_write_internal(void *opaque, gpa_t addr,
1099 idx, n_IRQ); 1103 idx, n_IRQ);
1100 mpic_irq_raise(opp, dst, ILR_INTTGT_INT); 1104 mpic_irq_raise(opp, dst, ILR_INTTGT_INT);
1101 } 1105 }
1106
1107 spin_unlock(&opp->lock);
1108 kvm_notify_acked_irq(opp->kvm, 0, notify_eoi);
1109 spin_lock(&opp->lock);
1110
1102 break; 1111 break;
1112 }
1103 default: 1113 default:
1104 break; 1114 break;
1105 } 1115 }
@@ -1639,14 +1649,34 @@ static void mpic_destroy(struct kvm_device *dev)
1639 unmap_mmio(opp); 1649 unmap_mmio(opp);
1640 } 1650 }
1641 1651
1652 dev->kvm->arch.mpic = NULL;
1642 kfree(opp); 1653 kfree(opp);
1643} 1654}
1644 1655
1656static int mpic_set_default_irq_routing(struct openpic *opp)
1657{
1658 struct kvm_irq_routing_entry *routing;
1659
1660 /* Create a nop default map, so that dereferencing it still works */
1661 routing = kzalloc((sizeof(*routing)), GFP_KERNEL);
1662 if (!routing)
1663 return -ENOMEM;
1664
1665 kvm_set_irq_routing(opp->kvm, routing, 0, 0);
1666
1667 kfree(routing);
1668 return 0;
1669}
1670
1645static int mpic_create(struct kvm_device *dev, u32 type) 1671static int mpic_create(struct kvm_device *dev, u32 type)
1646{ 1672{
1647 struct openpic *opp; 1673 struct openpic *opp;
1648 int ret; 1674 int ret;
1649 1675
1676 /* We only support one MPIC at a time for now */
1677 if (dev->kvm->arch.mpic)
1678 return -EINVAL;
1679
1650 opp = kzalloc(sizeof(struct openpic), GFP_KERNEL); 1680 opp = kzalloc(sizeof(struct openpic), GFP_KERNEL);
1651 if (!opp) 1681 if (!opp)
1652 return -ENOMEM; 1682 return -ENOMEM;
@@ -1691,7 +1721,15 @@ static int mpic_create(struct kvm_device *dev, u32 type)
1691 goto err; 1721 goto err;
1692 } 1722 }
1693 1723
1724 ret = mpic_set_default_irq_routing(opp);
1725 if (ret)
1726 goto err;
1727
1694 openpic_reset(opp); 1728 openpic_reset(opp);
1729
1730 smp_wmb();
1731 dev->kvm->arch.mpic = opp;
1732
1695 return 0; 1733 return 0;
1696 1734
1697err: 1735err:
@@ -1761,3 +1799,74 @@ void kvmppc_mpic_disconnect_vcpu(struct openpic *opp, struct kvm_vcpu *vcpu)
1761 opp->dst[vcpu->arch.irq_cpu_id].vcpu = NULL; 1799 opp->dst[vcpu->arch.irq_cpu_id].vcpu = NULL;
1762 kvm_device_put(opp->dev); 1800 kvm_device_put(opp->dev);
1763} 1801}
1802
1803/*
1804 * Return value:
1805 * < 0 Interrupt was ignored (masked or not delivered for other reasons)
1806 * = 0 Interrupt was coalesced (previous irq is still pending)
1807 * > 0 Number of CPUs interrupt was delivered to
1808 */
1809static int mpic_set_irq(struct kvm_kernel_irq_routing_entry *e,
1810 struct kvm *kvm, int irq_source_id, int level,
1811 bool line_status)
1812{
1813 u32 irq = e->irqchip.pin;
1814 struct openpic *opp = kvm->arch.mpic;
1815 unsigned long flags;
1816
1817 spin_lock_irqsave(&opp->lock, flags);
1818 openpic_set_irq(opp, irq, level);
1819 spin_unlock_irqrestore(&opp->lock, flags);
1820
1821 /* All code paths we care about don't check for the return value */
1822 return 0;
1823}
1824
1825int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
1826 struct kvm *kvm, int irq_source_id, int level, bool line_status)
1827{
1828 struct openpic *opp = kvm->arch.mpic;
1829 unsigned long flags;
1830
1831 spin_lock_irqsave(&opp->lock, flags);
1832
1833 /*
1834 * XXX We ignore the target address for now, as we only support
1835 * a single MSI bank.
1836 */
1837 openpic_msi_write(kvm->arch.mpic, MSIIR_OFFSET, e->msi.data);
1838 spin_unlock_irqrestore(&opp->lock, flags);
1839
1840 /* All code paths we care about don't check for the return value */
1841 return 0;
1842}
1843
1844int kvm_set_routing_entry(struct kvm_irq_routing_table *rt,
1845 struct kvm_kernel_irq_routing_entry *e,
1846 const struct kvm_irq_routing_entry *ue)
1847{
1848 int r = -EINVAL;
1849
1850 switch (ue->type) {
1851 case KVM_IRQ_ROUTING_IRQCHIP:
1852 e->set = mpic_set_irq;
1853 e->irqchip.irqchip = ue->u.irqchip.irqchip;
1854 e->irqchip.pin = ue->u.irqchip.pin;
1855 if (e->irqchip.pin >= KVM_IRQCHIP_NUM_PINS)
1856 goto out;
1857 rt->chip[ue->u.irqchip.irqchip][e->irqchip.pin] = ue->gsi;
1858 break;
1859 case KVM_IRQ_ROUTING_MSI:
1860 e->set = kvm_set_msi;
1861 e->msi.address_lo = ue->u.msi.address_lo;
1862 e->msi.address_hi = ue->u.msi.address_hi;
1863 e->msi.data = ue->u.msi.data;
1864 break;
1865 default:
1866 goto out;
1867 }
1868
1869 r = 0;
1870out:
1871 return r;
1872}