]> git.karo-electronics.de Git - karo-tx-linux.git/blob - virt/kvm/arm/vgic/vgic-v2.c
KVM: arm/arm64: vgic-new: Implement kvm_vgic_vcpu_pending_irq
[karo-tx-linux.git] / virt / kvm / arm / vgic / vgic-v2.c
1 /*
2  * Copyright (C) 2015, 2016 ARM Ltd.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15  */
16
17 #include <linux/irqchip/arm-gic.h>
18 #include <linux/kvm.h>
19 #include <linux/kvm_host.h>
20
21 #include "vgic.h"
22
23 /*
24  * Call this function to convert a u64 value to an unsigned long * bitmask
25  * in a way that works on both 32-bit and 64-bit LE and BE platforms.
26  *
27  * Warning: Calling this function may modify *val.
28  */
29 static unsigned long *u64_to_bitmask(u64 *val)
30 {
31 #if defined(CONFIG_CPU_BIG_ENDIAN) && BITS_PER_LONG == 32
32         *val = (*val >> 32) | (*val << 32);
33 #endif
34         return (unsigned long *)val;
35 }
36
37 void vgic_v2_process_maintenance(struct kvm_vcpu *vcpu)
38 {
39         struct vgic_v2_cpu_if *cpuif = &vcpu->arch.vgic_cpu.vgic_v2;
40
41         if (cpuif->vgic_misr & GICH_MISR_EOI) {
42                 u64 eisr = cpuif->vgic_eisr;
43                 unsigned long *eisr_bmap = u64_to_bitmask(&eisr);
44                 int lr;
45
46                 for_each_set_bit(lr, eisr_bmap, kvm_vgic_global_state.nr_lr) {
47                         u32 intid = cpuif->vgic_lr[lr] & GICH_LR_VIRTUALID;
48
49                         WARN_ON(cpuif->vgic_lr[lr] & GICH_LR_STATE);
50
51                         kvm_notify_acked_irq(vcpu->kvm, 0,
52                                              intid - VGIC_NR_PRIVATE_IRQS);
53                 }
54         }
55
56         /* check and disable underflow maintenance IRQ */
57         cpuif->vgic_hcr &= ~GICH_HCR_UIE;
58
59         /*
60          * In the next iterations of the vcpu loop, if we sync the
61          * vgic state after flushing it, but before entering the guest
62          * (this happens for pending signals and vmid rollovers), then
63          * make sure we don't pick up any old maintenance interrupts
64          * here.
65          */
66         cpuif->vgic_eisr = 0;
67 }
68
69 void vgic_v2_set_underflow(struct kvm_vcpu *vcpu)
70 {
71         struct vgic_v2_cpu_if *cpuif = &vcpu->arch.vgic_cpu.vgic_v2;
72
73         cpuif->vgic_hcr |= GICH_HCR_UIE;
74 }
75
76 /*
77  * transfer the content of the LRs back into the corresponding ap_list:
78  * - active bit is transferred as is
79  * - pending bit is
80  *   - transferred as is in case of edge sensitive IRQs
81  *   - set to the line-level (resample time) for level sensitive IRQs
82  */
83 void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
84 {
85         struct vgic_v2_cpu_if *cpuif = &vcpu->arch.vgic_cpu.vgic_v2;
86         int lr;
87
88         for (lr = 0; lr < vcpu->arch.vgic_cpu.used_lrs; lr++) {
89                 u32 val = cpuif->vgic_lr[lr];
90                 u32 intid = val & GICH_LR_VIRTUALID;
91                 struct vgic_irq *irq;
92
93                 irq = vgic_get_irq(vcpu->kvm, vcpu, intid);
94
95                 spin_lock(&irq->irq_lock);
96
97                 /* Always preserve the active bit */
98                 irq->active = !!(val & GICH_LR_ACTIVE_BIT);
99
100                 /* Edge is the only case where we preserve the pending bit */
101                 if (irq->config == VGIC_CONFIG_EDGE &&
102                     (val & GICH_LR_PENDING_BIT)) {
103                         irq->pending = true;
104
105                         if (vgic_irq_is_sgi(intid)) {
106                                 u32 cpuid = val & GICH_LR_PHYSID_CPUID;
107
108                                 cpuid >>= GICH_LR_PHYSID_CPUID_SHIFT;
109                                 irq->source |= (1 << cpuid);
110                         }
111                 }
112
113                 /* Clear soft pending state when level IRQs have been acked */
114                 if (irq->config == VGIC_CONFIG_LEVEL &&
115                     !(val & GICH_LR_PENDING_BIT)) {
116                         irq->soft_pending = false;
117                         irq->pending = irq->line_level;
118                 }
119
120                 spin_unlock(&irq->irq_lock);
121         }
122 }
123
124 /*
125  * Populates the particular LR with the state of a given IRQ:
126  * - for an edge sensitive IRQ the pending state is cleared in struct vgic_irq
127  * - for a level sensitive IRQ the pending state value is unchanged;
128  *   it is dictated directly by the input level
129  *
130  * If @irq describes an SGI with multiple sources, we choose the
131  * lowest-numbered source VCPU and clear that bit in the source bitmap.
132  *
133  * The irq_lock must be held by the caller.
134  */
135 void vgic_v2_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr)
136 {
137         u32 val = irq->intid;
138
139         if (irq->pending) {
140                 val |= GICH_LR_PENDING_BIT;
141
142                 if (irq->config == VGIC_CONFIG_EDGE)
143                         irq->pending = false;
144
145                 if (vgic_irq_is_sgi(irq->intid)) {
146                         u32 src = ffs(irq->source);
147
148                         BUG_ON(!src);
149                         val |= (src - 1) << GICH_LR_PHYSID_CPUID_SHIFT;
150                         irq->source &= ~(1 << (src - 1));
151                         if (irq->source)
152                                 irq->pending = true;
153                 }
154         }
155
156         if (irq->active)
157                 val |= GICH_LR_ACTIVE_BIT;
158
159         if (irq->hw) {
160                 val |= GICH_LR_HW;
161                 val |= irq->hwintid << GICH_LR_PHYSID_CPUID_SHIFT;
162         } else {
163                 if (irq->config == VGIC_CONFIG_LEVEL)
164                         val |= GICH_LR_EOI;
165         }
166
167         /* The GICv2 LR only holds five bits of priority. */
168         val |= (irq->priority >> 3) << GICH_LR_PRIORITY_SHIFT;
169
170         vcpu->arch.vgic_cpu.vgic_v2.vgic_lr[lr] = val;
171 }
172
173 void vgic_v2_clear_lr(struct kvm_vcpu *vcpu, int lr)
174 {
175         vcpu->arch.vgic_cpu.vgic_v2.vgic_lr[lr] = 0;
176 }