diff options
-rw-r--r-- | arch/arm/kvm/arm.c | 7 | ||||
-rw-r--r-- | include/kvm/arm_vgic.h | 1 | ||||
-rw-r--r-- | virt/kvm/arm/vgic.c | 42 |
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 | ||
262 | int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) | 262 | int 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); | |||
277 | int kvm_vgic_init(struct kvm *kvm); | 277 | int kvm_vgic_init(struct kvm *kvm); |
278 | int kvm_vgic_create(struct kvm *kvm); | 278 | int kvm_vgic_create(struct kvm *kvm); |
279 | void kvm_vgic_destroy(struct kvm *kvm); | 279 | void kvm_vgic_destroy(struct kvm *kvm); |
280 | int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu); | ||
281 | void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu); | 280 | void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu); |
282 | void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu); | 281 | void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu); |
283 | void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu); | 282 | void 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 | */ |
1732 | int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) | 1732 | static 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 | ||
1764 | void kvm_vgic_destroy(struct kvm *kvm) | 1759 | void 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 | |||
1852 | out: | 1859 | out: |
1853 | if (ret) | 1860 | if (ret) |
1854 | kvm_vgic_destroy(kvm); | 1861 | kvm_vgic_destroy(kvm); |
@@ -1867,6 +1874,7 @@ out: | |||
1867 | */ | 1874 | */ |
1868 | int kvm_vgic_init(struct kvm *kvm) | 1875 | int 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; |
1898 | out: | 1912 | out: |
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 | |||
1943 | out_unlock: | 1955 | out_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; |