diff options
author | Marc Zyngier <marc.zyngier@arm.com> | 2013-06-18 14:17:28 -0400 |
---|---|---|
committer | Christoffer Dall <christoffer.dall@linaro.org> | 2014-07-11 07:57:34 -0400 |
commit | ca85f623e37d096206e092ef037a145a60fa7f85 (patch) | |
tree | 1aefb3cd929f5707d18e486e77c95cf8b29dce47 /virt | |
parent | da8dafd1777cdd93091207952297d221a88e6479 (diff) |
KVM: ARM: introduce vgic_params structure
Move all the data specific to a given GIC implementation into its own
little structure.
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'virt')
-rw-r--r-- | virt/kvm/arm/vgic.c | 70 |
1 files changed, 33 insertions, 37 deletions
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c index 70f674bb13a1..f3a996d0a100 100644 --- a/virt/kvm/arm/vgic.c +++ b/virt/kvm/arm/vgic.c | |||
@@ -76,14 +76,6 @@ | |||
76 | #define IMPLEMENTER_ARM 0x43b | 76 | #define IMPLEMENTER_ARM 0x43b |
77 | #define GICC_ARCH_VERSION_V2 0x2 | 77 | #define GICC_ARCH_VERSION_V2 0x2 |
78 | 78 | ||
79 | /* Physical address of vgic virtual cpu interface */ | ||
80 | static phys_addr_t vgic_vcpu_base; | ||
81 | |||
82 | /* Virtual control interface base address */ | ||
83 | static void __iomem *vgic_vctrl_base; | ||
84 | |||
85 | static struct device_node *vgic_node; | ||
86 | |||
87 | #define ACCESS_READ_VALUE (1 << 0) | 79 | #define ACCESS_READ_VALUE (1 << 0) |
88 | #define ACCESS_READ_RAZ (0 << 0) | 80 | #define ACCESS_READ_RAZ (0 << 0) |
89 | #define ACCESS_READ_MASK(x) ((x) & (1 << 0)) | 81 | #define ACCESS_READ_MASK(x) ((x) & (1 << 0)) |
@@ -103,8 +95,7 @@ static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, struct vgic_lr lr_desc); | |||
103 | static void vgic_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); | 95 | static void vgic_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); |
104 | static void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); | 96 | static void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); |
105 | 97 | ||
106 | static u32 vgic_nr_lr; | 98 | static struct vgic_params vgic; |
107 | static unsigned int vgic_maint_irq; | ||
108 | 99 | ||
109 | static u32 *vgic_bitmap_get_reg(struct vgic_bitmap *x, | 100 | static u32 *vgic_bitmap_get_reg(struct vgic_bitmap *x, |
110 | int cpuid, u32 offset) | 101 | int cpuid, u32 offset) |
@@ -1206,7 +1197,7 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu) | |||
1206 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; | 1197 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; |
1207 | int lr; | 1198 | int lr; |
1208 | 1199 | ||
1209 | for_each_set_bit(lr, vgic_cpu->lr_used, vgic_cpu->nr_lr) { | 1200 | for_each_set_bit(lr, vgic_cpu->lr_used, vgic.nr_lr) { |
1210 | struct vgic_lr vlr = vgic_get_lr(vcpu, lr); | 1201 | struct vgic_lr vlr = vgic_get_lr(vcpu, lr); |
1211 | 1202 | ||
1212 | if (!vgic_irq_is_enabled(vcpu, vlr.irq)) { | 1203 | if (!vgic_irq_is_enabled(vcpu, vlr.irq)) { |
@@ -1250,8 +1241,8 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq) | |||
1250 | 1241 | ||
1251 | /* Try to use another LR for this interrupt */ | 1242 | /* Try to use another LR for this interrupt */ |
1252 | lr = find_first_zero_bit((unsigned long *)vgic_cpu->lr_used, | 1243 | lr = find_first_zero_bit((unsigned long *)vgic_cpu->lr_used, |
1253 | vgic_cpu->nr_lr); | 1244 | vgic.nr_lr); |
1254 | if (lr >= vgic_cpu->nr_lr) | 1245 | if (lr >= vgic.nr_lr) |
1255 | return false; | 1246 | return false; |
1256 | 1247 | ||
1257 | kvm_debug("LR%d allocated for IRQ%d %x\n", lr, irq, sgi_source_id); | 1248 | kvm_debug("LR%d allocated for IRQ%d %x\n", lr, irq, sgi_source_id); |
@@ -1377,7 +1368,6 @@ epilog: | |||
1377 | 1368 | ||
1378 | static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) | 1369 | static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) |
1379 | { | 1370 | { |
1380 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; | ||
1381 | u32 status = vgic_get_interrupt_status(vcpu); | 1371 | u32 status = vgic_get_interrupt_status(vcpu); |
1382 | bool level_pending = false; | 1372 | bool level_pending = false; |
1383 | 1373 | ||
@@ -1392,7 +1382,7 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) | |||
1392 | unsigned long *eisr_ptr = (unsigned long *)&eisr; | 1382 | unsigned long *eisr_ptr = (unsigned long *)&eisr; |
1393 | int lr; | 1383 | int lr; |
1394 | 1384 | ||
1395 | for_each_set_bit(lr, eisr_ptr, vgic_cpu->nr_lr) { | 1385 | for_each_set_bit(lr, eisr_ptr, vgic.nr_lr) { |
1396 | struct vgic_lr vlr = vgic_get_lr(vcpu, lr); | 1386 | struct vgic_lr vlr = vgic_get_lr(vcpu, lr); |
1397 | 1387 | ||
1398 | vgic_irq_clear_active(vcpu, vlr.irq); | 1388 | vgic_irq_clear_active(vcpu, vlr.irq); |
@@ -1440,7 +1430,7 @@ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu) | |||
1440 | elrsr_ptr = (unsigned long *)&elrsr; | 1430 | elrsr_ptr = (unsigned long *)&elrsr; |
1441 | 1431 | ||
1442 | /* Clear mappings for empty LRs */ | 1432 | /* Clear mappings for empty LRs */ |
1443 | for_each_set_bit(lr, elrsr_ptr, vgic_cpu->nr_lr) { | 1433 | for_each_set_bit(lr, elrsr_ptr, vgic.nr_lr) { |
1444 | struct vgic_lr vlr; | 1434 | struct vgic_lr vlr; |
1445 | 1435 | ||
1446 | if (!test_and_clear_bit(lr, vgic_cpu->lr_used)) | 1436 | if (!test_and_clear_bit(lr, vgic_cpu->lr_used)) |
@@ -1453,8 +1443,8 @@ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu) | |||
1453 | } | 1443 | } |
1454 | 1444 | ||
1455 | /* Check if we still have something up our sleeve... */ | 1445 | /* Check if we still have something up our sleeve... */ |
1456 | pending = find_first_zero_bit(elrsr_ptr, vgic_cpu->nr_lr); | 1446 | pending = find_first_zero_bit(elrsr_ptr, vgic.nr_lr); |
1457 | if (level_pending || pending < vgic_cpu->nr_lr) | 1447 | if (level_pending || pending < vgic.nr_lr) |
1458 | set_bit(vcpu->vcpu_id, &dist->irq_pending_on_cpu); | 1448 | set_bit(vcpu->vcpu_id, &dist->irq_pending_on_cpu); |
1459 | } | 1449 | } |
1460 | 1450 | ||
@@ -1643,7 +1633,12 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) | |||
1643 | vgic_cpu->vgic_irq_lr_map[i] = LR_EMPTY; | 1633 | vgic_cpu->vgic_irq_lr_map[i] = LR_EMPTY; |
1644 | } | 1634 | } |
1645 | 1635 | ||
1646 | vgic_cpu->nr_lr = vgic_nr_lr; | 1636 | /* |
1637 | * Store the number of LRs per vcpu, so we don't have to go | ||
1638 | * all the way to the distributor structure to find out. Only | ||
1639 | * assembly code should use this one. | ||
1640 | */ | ||
1641 | vgic_cpu->nr_lr = vgic.nr_lr; | ||
1647 | 1642 | ||
1648 | vgic_enable(vcpu); | 1643 | vgic_enable(vcpu); |
1649 | 1644 | ||
@@ -1652,7 +1647,7 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) | |||
1652 | 1647 | ||
1653 | static void vgic_init_maintenance_interrupt(void *info) | 1648 | static void vgic_init_maintenance_interrupt(void *info) |
1654 | { | 1649 | { |
1655 | enable_percpu_irq(vgic_maint_irq, 0); | 1650 | enable_percpu_irq(vgic.maint_irq, 0); |
1656 | } | 1651 | } |
1657 | 1652 | ||
1658 | static int vgic_cpu_notify(struct notifier_block *self, | 1653 | static int vgic_cpu_notify(struct notifier_block *self, |
@@ -1665,7 +1660,7 @@ static int vgic_cpu_notify(struct notifier_block *self, | |||
1665 | break; | 1660 | break; |
1666 | case CPU_DYING: | 1661 | case CPU_DYING: |
1667 | case CPU_DYING_FROZEN: | 1662 | case CPU_DYING_FROZEN: |
1668 | disable_percpu_irq(vgic_maint_irq); | 1663 | disable_percpu_irq(vgic.maint_irq); |
1669 | break; | 1664 | break; |
1670 | } | 1665 | } |
1671 | 1666 | ||
@@ -1681,6 +1676,7 @@ int kvm_vgic_hyp_init(void) | |||
1681 | int ret; | 1676 | int ret; |
1682 | struct resource vctrl_res; | 1677 | struct resource vctrl_res; |
1683 | struct resource vcpu_res; | 1678 | struct resource vcpu_res; |
1679 | struct device_node *vgic_node; | ||
1684 | 1680 | ||
1685 | vgic_node = of_find_compatible_node(NULL, NULL, "arm,cortex-a15-gic"); | 1681 | vgic_node = of_find_compatible_node(NULL, NULL, "arm,cortex-a15-gic"); |
1686 | if (!vgic_node) { | 1682 | if (!vgic_node) { |
@@ -1688,17 +1684,17 @@ int kvm_vgic_hyp_init(void) | |||
1688 | return -ENODEV; | 1684 | return -ENODEV; |
1689 | } | 1685 | } |
1690 | 1686 | ||
1691 | vgic_maint_irq = irq_of_parse_and_map(vgic_node, 0); | 1687 | vgic.maint_irq = irq_of_parse_and_map(vgic_node, 0); |
1692 | if (!vgic_maint_irq) { | 1688 | if (!vgic.maint_irq) { |
1693 | kvm_err("error getting vgic maintenance irq from DT\n"); | 1689 | kvm_err("error getting vgic maintenance irq from DT\n"); |
1694 | ret = -ENXIO; | 1690 | ret = -ENXIO; |
1695 | goto out; | 1691 | goto out; |
1696 | } | 1692 | } |
1697 | 1693 | ||
1698 | ret = request_percpu_irq(vgic_maint_irq, vgic_maintenance_handler, | 1694 | ret = request_percpu_irq(vgic.maint_irq, vgic_maintenance_handler, |
1699 | "vgic", kvm_get_running_vcpus()); | 1695 | "vgic", kvm_get_running_vcpus()); |
1700 | if (ret) { | 1696 | if (ret) { |
1701 | kvm_err("Cannot register interrupt %d\n", vgic_maint_irq); | 1697 | kvm_err("Cannot register interrupt %d\n", vgic.maint_irq); |
1702 | goto out; | 1698 | goto out; |
1703 | } | 1699 | } |
1704 | 1700 | ||
@@ -1714,18 +1710,18 @@ int kvm_vgic_hyp_init(void) | |||
1714 | goto out_free_irq; | 1710 | goto out_free_irq; |
1715 | } | 1711 | } |
1716 | 1712 | ||
1717 | vgic_vctrl_base = of_iomap(vgic_node, 2); | 1713 | vgic.vctrl_base = of_iomap(vgic_node, 2); |
1718 | if (!vgic_vctrl_base) { | 1714 | if (!vgic.vctrl_base) { |
1719 | kvm_err("Cannot ioremap VCTRL\n"); | 1715 | kvm_err("Cannot ioremap VCTRL\n"); |
1720 | ret = -ENOMEM; | 1716 | ret = -ENOMEM; |
1721 | goto out_free_irq; | 1717 | goto out_free_irq; |
1722 | } | 1718 | } |
1723 | 1719 | ||
1724 | vgic_nr_lr = readl_relaxed(vgic_vctrl_base + GICH_VTR); | 1720 | vgic.nr_lr = readl_relaxed(vgic.vctrl_base + GICH_VTR); |
1725 | vgic_nr_lr = (vgic_nr_lr & 0x3f) + 1; | 1721 | vgic.nr_lr = (vgic.nr_lr & 0x3f) + 1; |
1726 | 1722 | ||
1727 | ret = create_hyp_io_mappings(vgic_vctrl_base, | 1723 | ret = create_hyp_io_mappings(vgic.vctrl_base, |
1728 | vgic_vctrl_base + resource_size(&vctrl_res), | 1724 | vgic.vctrl_base + resource_size(&vctrl_res), |
1729 | vctrl_res.start); | 1725 | vctrl_res.start); |
1730 | if (ret) { | 1726 | if (ret) { |
1731 | kvm_err("Cannot map VCTRL into hyp\n"); | 1727 | kvm_err("Cannot map VCTRL into hyp\n"); |
@@ -1733,7 +1729,7 @@ int kvm_vgic_hyp_init(void) | |||
1733 | } | 1729 | } |
1734 | 1730 | ||
1735 | kvm_info("%s@%llx IRQ%d\n", vgic_node->name, | 1731 | kvm_info("%s@%llx IRQ%d\n", vgic_node->name, |
1736 | vctrl_res.start, vgic_maint_irq); | 1732 | vctrl_res.start, vgic.maint_irq); |
1737 | on_each_cpu(vgic_init_maintenance_interrupt, NULL, 1); | 1733 | on_each_cpu(vgic_init_maintenance_interrupt, NULL, 1); |
1738 | 1734 | ||
1739 | if (of_address_to_resource(vgic_node, 3, &vcpu_res)) { | 1735 | if (of_address_to_resource(vgic_node, 3, &vcpu_res)) { |
@@ -1741,14 +1737,14 @@ int kvm_vgic_hyp_init(void) | |||
1741 | ret = -ENXIO; | 1737 | ret = -ENXIO; |
1742 | goto out_unmap; | 1738 | goto out_unmap; |
1743 | } | 1739 | } |
1744 | vgic_vcpu_base = vcpu_res.start; | 1740 | vgic.vcpu_base = vcpu_res.start; |
1745 | 1741 | ||
1746 | goto out; | 1742 | goto out; |
1747 | 1743 | ||
1748 | out_unmap: | 1744 | out_unmap: |
1749 | iounmap(vgic_vctrl_base); | 1745 | iounmap(vgic.vctrl_base); |
1750 | out_free_irq: | 1746 | out_free_irq: |
1751 | free_percpu_irq(vgic_maint_irq, kvm_get_running_vcpus()); | 1747 | free_percpu_irq(vgic.maint_irq, kvm_get_running_vcpus()); |
1752 | out: | 1748 | out: |
1753 | of_node_put(vgic_node); | 1749 | of_node_put(vgic_node); |
1754 | return ret; | 1750 | return ret; |
@@ -1783,7 +1779,7 @@ int kvm_vgic_init(struct kvm *kvm) | |||
1783 | } | 1779 | } |
1784 | 1780 | ||
1785 | ret = kvm_phys_addr_ioremap(kvm, kvm->arch.vgic.vgic_cpu_base, | 1781 | ret = kvm_phys_addr_ioremap(kvm, kvm->arch.vgic.vgic_cpu_base, |
1786 | vgic_vcpu_base, KVM_VGIC_V2_CPU_SIZE); | 1782 | vgic.vcpu_base, KVM_VGIC_V2_CPU_SIZE); |
1787 | if (ret) { | 1783 | if (ret) { |
1788 | kvm_err("Unable to remap VGIC CPU to VCPU\n"); | 1784 | kvm_err("Unable to remap VGIC CPU to VCPU\n"); |
1789 | goto out; | 1785 | goto out; |
@@ -1829,7 +1825,7 @@ int kvm_vgic_create(struct kvm *kvm) | |||
1829 | } | 1825 | } |
1830 | 1826 | ||
1831 | spin_lock_init(&kvm->arch.vgic.lock); | 1827 | spin_lock_init(&kvm->arch.vgic.lock); |
1832 | kvm->arch.vgic.vctrl_base = vgic_vctrl_base; | 1828 | kvm->arch.vgic.vctrl_base = vgic.vctrl_base; |
1833 | kvm->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF; | 1829 | kvm->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF; |
1834 | kvm->arch.vgic.vgic_cpu_base = VGIC_ADDR_UNDEF; | 1830 | kvm->arch.vgic.vgic_cpu_base = VGIC_ADDR_UNDEF; |
1835 | 1831 | ||