diff options
Diffstat (limited to 'virt/kvm/arm/vgic.c')
-rw-r--r-- | virt/kvm/arm/vgic.c | 86 |
1 files changed, 76 insertions, 10 deletions
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c index a1fda798148e..9b63141a599d 100644 --- a/virt/kvm/arm/vgic.c +++ b/virt/kvm/arm/vgic.c | |||
@@ -106,6 +106,21 @@ static void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); | |||
106 | static const struct vgic_ops *vgic_ops; | 106 | static const struct vgic_ops *vgic_ops; |
107 | static const struct vgic_params *vgic; | 107 | static const struct vgic_params *vgic; |
108 | 108 | ||
109 | static void add_sgi_source(struct kvm_vcpu *vcpu, int irq, int source) | ||
110 | { | ||
111 | vcpu->kvm->arch.vgic.vm_ops.add_sgi_source(vcpu, irq, source); | ||
112 | } | ||
113 | |||
114 | static bool queue_sgi(struct kvm_vcpu *vcpu, int irq) | ||
115 | { | ||
116 | return vcpu->kvm->arch.vgic.vm_ops.queue_sgi(vcpu, irq); | ||
117 | } | ||
118 | |||
119 | int kvm_vgic_map_resources(struct kvm *kvm) | ||
120 | { | ||
121 | return kvm->arch.vgic.vm_ops.map_resources(kvm, vgic); | ||
122 | } | ||
123 | |||
109 | /* | 124 | /* |
110 | * struct vgic_bitmap contains a bitmap made of unsigned longs, but | 125 | * struct vgic_bitmap contains a bitmap made of unsigned longs, but |
111 | * extracts u32s out of them. | 126 | * extracts u32s out of them. |
@@ -762,6 +777,13 @@ static bool handle_mmio_sgi_reg(struct kvm_vcpu *vcpu, | |||
762 | return false; | 777 | return false; |
763 | } | 778 | } |
764 | 779 | ||
780 | static void vgic_v2_add_sgi_source(struct kvm_vcpu *vcpu, int irq, int source) | ||
781 | { | ||
782 | struct vgic_dist *dist = &vcpu->kvm->arch.vgic; | ||
783 | |||
784 | *vgic_get_sgi_sources(dist, vcpu->vcpu_id, irq) |= 1 << source; | ||
785 | } | ||
786 | |||
765 | /** | 787 | /** |
766 | * vgic_unqueue_irqs - move pending IRQs from LRs to the distributor | 788 | * vgic_unqueue_irqs - move pending IRQs from LRs to the distributor |
767 | * @vgic_cpu: Pointer to the vgic_cpu struct holding the LRs | 789 | * @vgic_cpu: Pointer to the vgic_cpu struct holding the LRs |
@@ -776,9 +798,7 @@ static bool handle_mmio_sgi_reg(struct kvm_vcpu *vcpu, | |||
776 | */ | 798 | */ |
777 | static void vgic_unqueue_irqs(struct kvm_vcpu *vcpu) | 799 | static void vgic_unqueue_irqs(struct kvm_vcpu *vcpu) |
778 | { | 800 | { |
779 | struct vgic_dist *dist = &vcpu->kvm->arch.vgic; | ||
780 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; | 801 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; |
781 | int vcpu_id = vcpu->vcpu_id; | ||
782 | int i; | 802 | int i; |
783 | 803 | ||
784 | for_each_set_bit(i, vgic_cpu->lr_used, vgic_cpu->nr_lr) { | 804 | for_each_set_bit(i, vgic_cpu->lr_used, vgic_cpu->nr_lr) { |
@@ -805,7 +825,7 @@ static void vgic_unqueue_irqs(struct kvm_vcpu *vcpu) | |||
805 | */ | 825 | */ |
806 | vgic_dist_irq_set_pending(vcpu, lr.irq); | 826 | vgic_dist_irq_set_pending(vcpu, lr.irq); |
807 | if (lr.irq < VGIC_NR_SGIS) | 827 | if (lr.irq < VGIC_NR_SGIS) |
808 | *vgic_get_sgi_sources(dist, vcpu_id, lr.irq) |= 1 << lr.source; | 828 | add_sgi_source(vcpu, lr.irq, lr.source); |
809 | lr.state &= ~LR_STATE_PENDING; | 829 | lr.state &= ~LR_STATE_PENDING; |
810 | vgic_set_lr(vcpu, i, lr); | 830 | vgic_set_lr(vcpu, i, lr); |
811 | 831 | ||
@@ -1159,6 +1179,7 @@ static bool vgic_v2_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run, | |||
1159 | * | 1179 | * |
1160 | * returns true if the MMIO access has been performed in kernel space, | 1180 | * returns true if the MMIO access has been performed in kernel space, |
1161 | * and false if it needs to be emulated in user space. | 1181 | * and false if it needs to be emulated in user space. |
1182 | * Calls the actual handling routine for the selected VGIC model. | ||
1162 | */ | 1183 | */ |
1163 | bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run, | 1184 | bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run, |
1164 | struct kvm_exit_mmio *mmio) | 1185 | struct kvm_exit_mmio *mmio) |
@@ -1166,7 +1187,12 @@ bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run, | |||
1166 | if (!irqchip_in_kernel(vcpu->kvm)) | 1187 | if (!irqchip_in_kernel(vcpu->kvm)) |
1167 | return false; | 1188 | return false; |
1168 | 1189 | ||
1169 | return vgic_v2_handle_mmio(vcpu, run, mmio); | 1190 | /* |
1191 | * This will currently call either vgic_v2_handle_mmio() or | ||
1192 | * vgic_v3_handle_mmio(), which in turn will call | ||
1193 | * vgic_handle_mmio_range() defined above. | ||
1194 | */ | ||
1195 | return vcpu->kvm->arch.vgic.vm_ops.handle_mmio(vcpu, run, mmio); | ||
1170 | } | 1196 | } |
1171 | 1197 | ||
1172 | static u8 *vgic_get_sgi_sources(struct vgic_dist *dist, int vcpu_id, int sgi) | 1198 | static u8 *vgic_get_sgi_sources(struct vgic_dist *dist, int vcpu_id, int sgi) |
@@ -1418,7 +1444,7 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq) | |||
1418 | return true; | 1444 | return true; |
1419 | } | 1445 | } |
1420 | 1446 | ||
1421 | static bool vgic_queue_sgi(struct kvm_vcpu *vcpu, int irq) | 1447 | static bool vgic_v2_queue_sgi(struct kvm_vcpu *vcpu, int irq) |
1422 | { | 1448 | { |
1423 | struct vgic_dist *dist = &vcpu->kvm->arch.vgic; | 1449 | struct vgic_dist *dist = &vcpu->kvm->arch.vgic; |
1424 | unsigned long sources; | 1450 | unsigned long sources; |
@@ -1493,7 +1519,7 @@ static void __kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu) | |||
1493 | 1519 | ||
1494 | /* SGIs */ | 1520 | /* SGIs */ |
1495 | for_each_set_bit(i, vgic_cpu->pending_percpu, VGIC_NR_SGIS) { | 1521 | for_each_set_bit(i, vgic_cpu->pending_percpu, VGIC_NR_SGIS) { |
1496 | if (!vgic_queue_sgi(vcpu, i)) | 1522 | if (!queue_sgi(vcpu, i)) |
1497 | overflow = 1; | 1523 | overflow = 1; |
1498 | } | 1524 | } |
1499 | 1525 | ||
@@ -1883,6 +1909,16 @@ void kvm_vgic_destroy(struct kvm *kvm) | |||
1883 | dist->nr_cpus = 0; | 1909 | dist->nr_cpus = 0; |
1884 | } | 1910 | } |
1885 | 1911 | ||
1912 | static int vgic_v2_init_model(struct kvm *kvm) | ||
1913 | { | ||
1914 | int i; | ||
1915 | |||
1916 | for (i = VGIC_NR_PRIVATE_IRQS; i < kvm->arch.vgic.nr_irqs; i += 4) | ||
1917 | vgic_set_target_reg(kvm, 0, i); | ||
1918 | |||
1919 | return 0; | ||
1920 | } | ||
1921 | |||
1886 | /* | 1922 | /* |
1887 | * Allocate and initialize the various data structures. Must be called | 1923 | * Allocate and initialize the various data structures. Must be called |
1888 | * with kvm->lock held! | 1924 | * with kvm->lock held! |
@@ -1942,8 +1978,9 @@ static int vgic_init(struct kvm *kvm) | |||
1942 | if (ret) | 1978 | if (ret) |
1943 | goto out; | 1979 | goto out; |
1944 | 1980 | ||
1945 | for (i = VGIC_NR_PRIVATE_IRQS; i < dist->nr_irqs; i += 4) | 1981 | ret = kvm->arch.vgic.vm_ops.init_model(kvm); |
1946 | vgic_set_target_reg(kvm, 0, i); | 1982 | if (ret) |
1983 | goto out; | ||
1947 | 1984 | ||
1948 | kvm_for_each_vcpu(vcpu_id, vcpu, kvm) { | 1985 | kvm_for_each_vcpu(vcpu_id, vcpu, kvm) { |
1949 | ret = vgic_vcpu_init_maps(vcpu, nr_irqs); | 1986 | ret = vgic_vcpu_init_maps(vcpu, nr_irqs); |
@@ -1980,7 +2017,8 @@ out: | |||
1980 | * can't do this at creation time, because user space must first set the | 2017 | * can't do this at creation time, because user space must first set the |
1981 | * virtual CPU interface address in the guest physical address space. | 2018 | * virtual CPU interface address in the guest physical address space. |
1982 | */ | 2019 | */ |
1983 | int kvm_vgic_map_resources(struct kvm *kvm) | 2020 | static int vgic_v2_map_resources(struct kvm *kvm, |
2021 | const struct vgic_params *params) | ||
1984 | { | 2022 | { |
1985 | int ret = 0; | 2023 | int ret = 0; |
1986 | 2024 | ||
@@ -2010,7 +2048,7 @@ int kvm_vgic_map_resources(struct kvm *kvm) | |||
2010 | } | 2048 | } |
2011 | 2049 | ||
2012 | ret = kvm_phys_addr_ioremap(kvm, kvm->arch.vgic.vgic_cpu_base, | 2050 | ret = kvm_phys_addr_ioremap(kvm, kvm->arch.vgic.vgic_cpu_base, |
2013 | vgic->vcpu_base, KVM_VGIC_V2_CPU_SIZE, | 2051 | params->vcpu_base, KVM_VGIC_V2_CPU_SIZE, |
2014 | true); | 2052 | true); |
2015 | if (ret) { | 2053 | if (ret) { |
2016 | kvm_err("Unable to remap VGIC CPU to VCPU\n"); | 2054 | kvm_err("Unable to remap VGIC CPU to VCPU\n"); |
@@ -2025,6 +2063,30 @@ out: | |||
2025 | return ret; | 2063 | return ret; |
2026 | } | 2064 | } |
2027 | 2065 | ||
2066 | static void vgic_v2_init_emulation(struct kvm *kvm) | ||
2067 | { | ||
2068 | struct vgic_dist *dist = &kvm->arch.vgic; | ||
2069 | |||
2070 | dist->vm_ops.handle_mmio = vgic_v2_handle_mmio; | ||
2071 | dist->vm_ops.queue_sgi = vgic_v2_queue_sgi; | ||
2072 | dist->vm_ops.add_sgi_source = vgic_v2_add_sgi_source; | ||
2073 | dist->vm_ops.init_model = vgic_v2_init_model; | ||
2074 | dist->vm_ops.map_resources = vgic_v2_map_resources; | ||
2075 | } | ||
2076 | |||
2077 | static int init_vgic_model(struct kvm *kvm, int type) | ||
2078 | { | ||
2079 | switch (type) { | ||
2080 | case KVM_DEV_TYPE_ARM_VGIC_V2: | ||
2081 | vgic_v2_init_emulation(kvm); | ||
2082 | break; | ||
2083 | default: | ||
2084 | return -ENODEV; | ||
2085 | } | ||
2086 | |||
2087 | return 0; | ||
2088 | } | ||
2089 | |||
2028 | int kvm_vgic_create(struct kvm *kvm, u32 type) | 2090 | int kvm_vgic_create(struct kvm *kvm, u32 type) |
2029 | { | 2091 | { |
2030 | int i, vcpu_lock_idx = -1, ret; | 2092 | int i, vcpu_lock_idx = -1, ret; |
@@ -2055,6 +2117,10 @@ int kvm_vgic_create(struct kvm *kvm, u32 type) | |||
2055 | } | 2117 | } |
2056 | ret = 0; | 2118 | ret = 0; |
2057 | 2119 | ||
2120 | ret = init_vgic_model(kvm, type); | ||
2121 | if (ret) | ||
2122 | goto out_unlock; | ||
2123 | |||
2058 | spin_lock_init(&kvm->arch.vgic.lock); | 2124 | spin_lock_init(&kvm->arch.vgic.lock); |
2059 | kvm->arch.vgic.in_kernel = true; | 2125 | kvm->arch.vgic.in_kernel = true; |
2060 | kvm->arch.vgic.vgic_model = type; | 2126 | kvm->arch.vgic.vgic_model = type; |