aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm/mpic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kvm/mpic.c')
-rw-r--r--arch/powerpc/kvm/mpic.c111
1 files changed, 110 insertions, 1 deletions
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}