aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/kvm/arm.c7
-rw-r--r--include/kvm/arm_vgic.h1
-rw-r--r--virt/kvm/arm/vgic.c42
3 files changed, 29 insertions, 21 deletions
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index c1a11496817b..40bc3df6d87b 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -261,16 +261,9 @@ int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
261 261
262int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) 262int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
263{ 263{
264 int ret;
265
266 /* Force users to call KVM_ARM_VCPU_INIT */ 264 /* Force users to call KVM_ARM_VCPU_INIT */
267 vcpu->arch.target = -1; 265 vcpu->arch.target = -1;
268 266
269 /* Set up VGIC */
270 ret = kvm_vgic_vcpu_init(vcpu);
271 if (ret)
272 return ret;
273
274 /* Set up the timer */ 267 /* Set up the timer */
275 kvm_timer_vcpu_init(vcpu); 268 kvm_timer_vcpu_init(vcpu);
276 269
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index aa20d4a7242f..2f2aac8448a4 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -277,7 +277,6 @@ int kvm_vgic_hyp_init(void);
277int kvm_vgic_init(struct kvm *kvm); 277int kvm_vgic_init(struct kvm *kvm);
278int kvm_vgic_create(struct kvm *kvm); 278int kvm_vgic_create(struct kvm *kvm);
279void kvm_vgic_destroy(struct kvm *kvm); 279void kvm_vgic_destroy(struct kvm *kvm);
280int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu);
281void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu); 280void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu);
282void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu); 281void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
283void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu); 282void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 725d829ad1d9..ac2b44d58e60 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -1729,15 +1729,12 @@ static int vgic_vcpu_init_maps(struct kvm_vcpu *vcpu, int nr_irqs)
1729 * Initialize the vgic_cpu struct and vgic_dist struct fields pertaining to 1729 * Initialize the vgic_cpu struct and vgic_dist struct fields pertaining to
1730 * this vcpu and enable the VGIC for this VCPU 1730 * this vcpu and enable the VGIC for this VCPU
1731 */ 1731 */
1732int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) 1732static void kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
1733{ 1733{
1734 struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; 1734 struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
1735 struct vgic_dist *dist = &vcpu->kvm->arch.vgic; 1735 struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
1736 int i; 1736 int i;
1737 1737
1738 if (vcpu->vcpu_id >= dist->nr_cpus)
1739 return -EBUSY;
1740
1741 for (i = 0; i < dist->nr_irqs; i++) { 1738 for (i = 0; i < dist->nr_irqs; i++) {
1742 if (i < VGIC_NR_PPIS) 1739 if (i < VGIC_NR_PPIS)
1743 vgic_bitmap_set_irq_val(&dist->irq_enabled, 1740 vgic_bitmap_set_irq_val(&dist->irq_enabled,
@@ -1757,8 +1754,6 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
1757 vgic_cpu->nr_lr = vgic->nr_lr; 1754 vgic_cpu->nr_lr = vgic->nr_lr;
1758 1755
1759 vgic_enable(vcpu); 1756 vgic_enable(vcpu);
1760
1761 return 0;
1762} 1757}
1763 1758
1764void kvm_vgic_destroy(struct kvm *kvm) 1759void kvm_vgic_destroy(struct kvm *kvm)
@@ -1802,8 +1797,17 @@ static int vgic_init_maps(struct kvm *kvm)
1802 int nr_cpus, nr_irqs; 1797 int nr_cpus, nr_irqs;
1803 int ret, i; 1798 int ret, i;
1804 1799
1805 nr_cpus = dist->nr_cpus = KVM_MAX_VCPUS; 1800 if (dist->nr_cpus) /* Already allocated */
1801 return 0;
1802
1803 nr_cpus = dist->nr_cpus = atomic_read(&kvm->online_vcpus);
1804 if (!nr_cpus) /* No vcpus? Can't be good... */
1805 return -EINVAL;
1806 1806
1807 /*
1808 * If nobody configured the number of interrupts, use the
1809 * legacy one.
1810 */
1807 if (!dist->nr_irqs) 1811 if (!dist->nr_irqs)
1808 dist->nr_irqs = VGIC_NR_IRQS_LEGACY; 1812 dist->nr_irqs = VGIC_NR_IRQS_LEGACY;
1809 1813
@@ -1849,6 +1853,9 @@ static int vgic_init_maps(struct kvm *kvm)
1849 } 1853 }
1850 } 1854 }
1851 1855
1856 for (i = VGIC_NR_PRIVATE_IRQS; i < dist->nr_irqs; i += 4)
1857 vgic_set_target_reg(kvm, 0, i);
1858
1852out: 1859out:
1853 if (ret) 1860 if (ret)
1854 kvm_vgic_destroy(kvm); 1861 kvm_vgic_destroy(kvm);
@@ -1867,6 +1874,7 @@ out:
1867 */ 1874 */
1868int kvm_vgic_init(struct kvm *kvm) 1875int kvm_vgic_init(struct kvm *kvm)
1869{ 1876{
1877 struct kvm_vcpu *vcpu;
1870 int ret = 0, i; 1878 int ret = 0, i;
1871 1879
1872 if (!irqchip_in_kernel(kvm)) 1880 if (!irqchip_in_kernel(kvm))
@@ -1884,6 +1892,12 @@ int kvm_vgic_init(struct kvm *kvm)
1884 goto out; 1892 goto out;
1885 } 1893 }
1886 1894
1895 ret = vgic_init_maps(kvm);
1896 if (ret) {
1897 kvm_err("Unable to allocate maps\n");
1898 goto out;
1899 }
1900
1887 ret = kvm_phys_addr_ioremap(kvm, kvm->arch.vgic.vgic_cpu_base, 1901 ret = kvm_phys_addr_ioremap(kvm, kvm->arch.vgic.vgic_cpu_base,
1888 vgic->vcpu_base, KVM_VGIC_V2_CPU_SIZE); 1902 vgic->vcpu_base, KVM_VGIC_V2_CPU_SIZE);
1889 if (ret) { 1903 if (ret) {
@@ -1891,11 +1905,13 @@ int kvm_vgic_init(struct kvm *kvm)
1891 goto out; 1905 goto out;
1892 } 1906 }
1893 1907
1894 for (i = VGIC_NR_PRIVATE_IRQS; i < kvm->arch.vgic.nr_irqs; i += 4) 1908 kvm_for_each_vcpu(i, vcpu, kvm)
1895 vgic_set_target_reg(kvm, 0, i); 1909 kvm_vgic_vcpu_init(vcpu);
1896 1910
1897 kvm->arch.vgic.ready = true; 1911 kvm->arch.vgic.ready = true;
1898out: 1912out:
1913 if (ret)
1914 kvm_vgic_destroy(kvm);
1899 mutex_unlock(&kvm->lock); 1915 mutex_unlock(&kvm->lock);
1900 return ret; 1916 return ret;
1901} 1917}
@@ -1936,10 +1952,6 @@ int kvm_vgic_create(struct kvm *kvm)
1936 kvm->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF; 1952 kvm->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF;
1937 kvm->arch.vgic.vgic_cpu_base = VGIC_ADDR_UNDEF; 1953 kvm->arch.vgic.vgic_cpu_base = VGIC_ADDR_UNDEF;
1938 1954
1939 ret = vgic_init_maps(kvm);
1940 if (ret)
1941 kvm_err("Unable to allocate maps\n");
1942
1943out_unlock: 1955out_unlock:
1944 for (; vcpu_lock_idx >= 0; vcpu_lock_idx--) { 1956 for (; vcpu_lock_idx >= 0; vcpu_lock_idx--) {
1945 vcpu = kvm_get_vcpu(kvm, vcpu_lock_idx); 1957 vcpu = kvm_get_vcpu(kvm, vcpu_lock_idx);
@@ -2140,6 +2152,10 @@ static int vgic_attr_regs_access(struct kvm_device *dev,
2140 2152
2141 mutex_lock(&dev->kvm->lock); 2153 mutex_lock(&dev->kvm->lock);
2142 2154
2155 ret = vgic_init_maps(dev->kvm);
2156 if (ret)
2157 goto out;
2158
2143 if (cpuid >= atomic_read(&dev->kvm->online_vcpus)) { 2159 if (cpuid >= atomic_read(&dev->kvm->online_vcpus)) {
2144 ret = -EINVAL; 2160 ret = -EINVAL;
2145 goto out; 2161 goto out;