aboutsummaryrefslogtreecommitdiffstats
path: root/virt
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2014-12-04 10:02:24 -0500
committerChristoffer Dall <christoffer.dall@linaro.org>2014-12-13 08:15:52 -0500
commit6d3cfbe21bef5b66530b50ad16c88fdc71a04c35 (patch)
treeb5f375258f0273acdab23d900ac9b06c642a8e5f /virt
parent957db105c99792ae8ef61ffc9ae77d910f6471da (diff)
arm/arm64: KVM: vgic: move reset initialization into vgic_init_maps()
VGIC initialization currently happens in three phases: (1) kvm_vgic_create() (triggered by userspace GIC creation) (2) vgic_init_maps() (triggered by userspace GIC register read/write requests, or from kvm_vgic_init() if not already run) (3) kvm_vgic_init() (triggered by first VM run) We were doing initialization of some state to correspond with the state of a freshly-reset GIC in kvm_vgic_init(); this is too late, since it will overwrite changes made by userspace using the register access APIs before the VM is run. Move this initialization earlier, into the vgic_init_maps() phase. This fixes a bug where QEMU could successfully restore a saved VM state snapshot into a VM that had already been run, but could not restore it "from cold" using the -loadvm command line option (the symptoms being that the restored VM would run but interrupts were ignored). Finally rename vgic_init_maps to vgic_init and renamed kvm_vgic_init to kvm_vgic_map_resources. [ This patch is originally written by Peter Maydell, but I have modified it somewhat heavily, renaming various bits and moving code around. If something is broken, I am to be blamed. - Christoffer ] Acked-by: Marc Zyngier <marc.zyngier@arm.com> Reviewed-by: Eric Auger <eric.auger@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Diffstat (limited to 'virt')
-rw-r--r--virt/kvm/arm/vgic.c77
1 files changed, 32 insertions, 45 deletions
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 21e035cc5460..1ce4e364c1e0 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -91,6 +91,7 @@
91#define ACCESS_WRITE_VALUE (3 << 1) 91#define ACCESS_WRITE_VALUE (3 << 1)
92#define ACCESS_WRITE_MASK(x) ((x) & (3 << 1)) 92#define ACCESS_WRITE_MASK(x) ((x) & (3 << 1))
93 93
94static int vgic_init(struct kvm *kvm);
94static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu); 95static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu);
95static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu); 96static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu);
96static void vgic_update_state(struct kvm *kvm); 97static void vgic_update_state(struct kvm *kvm);
@@ -1732,39 +1733,14 @@ static int vgic_vcpu_init_maps(struct kvm_vcpu *vcpu, int nr_irqs)
1732 1733
1733 int sz = (nr_irqs - VGIC_NR_PRIVATE_IRQS) / 8; 1734 int sz = (nr_irqs - VGIC_NR_PRIVATE_IRQS) / 8;
1734 vgic_cpu->pending_shared = kzalloc(sz, GFP_KERNEL); 1735 vgic_cpu->pending_shared = kzalloc(sz, GFP_KERNEL);
1735 vgic_cpu->vgic_irq_lr_map = kzalloc(nr_irqs, GFP_KERNEL); 1736 vgic_cpu->vgic_irq_lr_map = kmalloc(nr_irqs, GFP_KERNEL);
1736 1737
1737 if (!vgic_cpu->pending_shared || !vgic_cpu->vgic_irq_lr_map) { 1738 if (!vgic_cpu->pending_shared || !vgic_cpu->vgic_irq_lr_map) {
1738 kvm_vgic_vcpu_destroy(vcpu); 1739 kvm_vgic_vcpu_destroy(vcpu);
1739 return -ENOMEM; 1740 return -ENOMEM;
1740 } 1741 }
1741 1742
1742 return 0; 1743 memset(vgic_cpu->vgic_irq_lr_map, LR_EMPTY, nr_irqs);
1743}
1744
1745/**
1746 * kvm_vgic_vcpu_init - Initialize per-vcpu VGIC state
1747 * @vcpu: pointer to the vcpu struct
1748 *
1749 * Initialize the vgic_cpu struct and vgic_dist struct fields pertaining to
1750 * this vcpu and enable the VGIC for this VCPU
1751 */
1752static void kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
1753{
1754 struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
1755 struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
1756 int i;
1757
1758 for (i = 0; i < dist->nr_irqs; i++) {
1759 if (i < VGIC_NR_PPIS)
1760 vgic_bitmap_set_irq_val(&dist->irq_enabled,
1761 vcpu->vcpu_id, i, 1);
1762 if (i < VGIC_NR_PRIVATE_IRQS)
1763 vgic_bitmap_set_irq_val(&dist->irq_cfg,
1764 vcpu->vcpu_id, i, VGIC_CFG_EDGE);
1765
1766 vgic_cpu->vgic_irq_lr_map[i] = LR_EMPTY;
1767 }
1768 1744
1769 /* 1745 /*
1770 * Store the number of LRs per vcpu, so we don't have to go 1746 * Store the number of LRs per vcpu, so we don't have to go
@@ -1773,7 +1749,7 @@ static void kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
1773 */ 1749 */
1774 vgic_cpu->nr_lr = vgic->nr_lr; 1750 vgic_cpu->nr_lr = vgic->nr_lr;
1775 1751
1776 vgic_enable(vcpu); 1752 return 0;
1777} 1753}
1778 1754
1779void kvm_vgic_destroy(struct kvm *kvm) 1755void kvm_vgic_destroy(struct kvm *kvm)
@@ -1810,12 +1786,12 @@ void kvm_vgic_destroy(struct kvm *kvm)
1810 * Allocate and initialize the various data structures. Must be called 1786 * Allocate and initialize the various data structures. Must be called
1811 * with kvm->lock held! 1787 * with kvm->lock held!
1812 */ 1788 */
1813static int vgic_init_maps(struct kvm *kvm) 1789static int vgic_init(struct kvm *kvm)
1814{ 1790{
1815 struct vgic_dist *dist = &kvm->arch.vgic; 1791 struct vgic_dist *dist = &kvm->arch.vgic;
1816 struct kvm_vcpu *vcpu; 1792 struct kvm_vcpu *vcpu;
1817 int nr_cpus, nr_irqs; 1793 int nr_cpus, nr_irqs;
1818 int ret, i; 1794 int ret, i, vcpu_id;
1819 1795
1820 if (dist->nr_cpus) /* Already allocated */ 1796 if (dist->nr_cpus) /* Already allocated */
1821 return 0; 1797 return 0;
@@ -1865,16 +1841,28 @@ static int vgic_init_maps(struct kvm *kvm)
1865 if (ret) 1841 if (ret)
1866 goto out; 1842 goto out;
1867 1843
1868 kvm_for_each_vcpu(i, vcpu, kvm) { 1844 for (i = VGIC_NR_PRIVATE_IRQS; i < dist->nr_irqs; i += 4)
1845 vgic_set_target_reg(kvm, 0, i);
1846
1847 kvm_for_each_vcpu(vcpu_id, vcpu, kvm) {
1869 ret = vgic_vcpu_init_maps(vcpu, nr_irqs); 1848 ret = vgic_vcpu_init_maps(vcpu, nr_irqs);
1870 if (ret) { 1849 if (ret) {
1871 kvm_err("VGIC: Failed to allocate vcpu memory\n"); 1850 kvm_err("VGIC: Failed to allocate vcpu memory\n");
1872 break; 1851 break;
1873 } 1852 }
1874 }
1875 1853
1876 for (i = VGIC_NR_PRIVATE_IRQS; i < dist->nr_irqs; i += 4) 1854 for (i = 0; i < dist->nr_irqs; i++) {
1877 vgic_set_target_reg(kvm, 0, i); 1855 if (i < VGIC_NR_PPIS)
1856 vgic_bitmap_set_irq_val(&dist->irq_enabled,
1857 vcpu->vcpu_id, i, 1);
1858 if (i < VGIC_NR_PRIVATE_IRQS)
1859 vgic_bitmap_set_irq_val(&dist->irq_cfg,
1860 vcpu->vcpu_id, i,
1861 VGIC_CFG_EDGE);
1862 }
1863
1864 vgic_enable(vcpu);
1865 }
1878 1866
1879out: 1867out:
1880 if (ret) 1868 if (ret)
@@ -1884,18 +1872,16 @@ out:
1884} 1872}
1885 1873
1886/** 1874/**
1887 * kvm_vgic_init - Initialize global VGIC state before running any VCPUs 1875 * kvm_vgic_map_resources - Configure global VGIC state before running any VCPUs
1888 * @kvm: pointer to the kvm struct 1876 * @kvm: pointer to the kvm struct
1889 * 1877 *
1890 * Map the virtual CPU interface into the VM before running any VCPUs. We 1878 * Map the virtual CPU interface into the VM before running any VCPUs. We
1891 * can't do this at creation time, because user space must first set the 1879 * can't do this at creation time, because user space must first set the
1892 * virtual CPU interface address in the guest physical address space. Also 1880 * virtual CPU interface address in the guest physical address space.
1893 * initialize the ITARGETSRn regs to 0 on the emulated distributor.
1894 */ 1881 */
1895int kvm_vgic_init(struct kvm *kvm) 1882int kvm_vgic_map_resources(struct kvm *kvm)
1896{ 1883{
1897 struct kvm_vcpu *vcpu; 1884 int ret = 0;
1898 int ret = 0, i;
1899 1885
1900 if (!irqchip_in_kernel(kvm)) 1886 if (!irqchip_in_kernel(kvm))
1901 return 0; 1887 return 0;
@@ -1912,7 +1898,11 @@ int kvm_vgic_init(struct kvm *kvm)
1912 goto out; 1898 goto out;
1913 } 1899 }
1914 1900
1915 ret = vgic_init_maps(kvm); 1901 /*
1902 * Initialize the vgic if this hasn't already been done on demand by
1903 * accessing the vgic state from userspace.
1904 */
1905 ret = vgic_init(kvm);
1916 if (ret) { 1906 if (ret) {
1917 kvm_err("Unable to allocate maps\n"); 1907 kvm_err("Unable to allocate maps\n");
1918 goto out; 1908 goto out;
@@ -1926,9 +1916,6 @@ int kvm_vgic_init(struct kvm *kvm)
1926 goto out; 1916 goto out;
1927 } 1917 }
1928 1918
1929 kvm_for_each_vcpu(i, vcpu, kvm)
1930 kvm_vgic_vcpu_init(vcpu);
1931
1932 kvm->arch.vgic.ready = true; 1919 kvm->arch.vgic.ready = true;
1933out: 1920out:
1934 if (ret) 1921 if (ret)
@@ -2173,7 +2160,7 @@ static int vgic_attr_regs_access(struct kvm_device *dev,
2173 2160
2174 mutex_lock(&dev->kvm->lock); 2161 mutex_lock(&dev->kvm->lock);
2175 2162
2176 ret = vgic_init_maps(dev->kvm); 2163 ret = vgic_init(dev->kvm);
2177 if (ret) 2164 if (ret)
2178 goto out; 2165 goto out;
2179 2166