aboutsummaryrefslogtreecommitdiffstats
path: root/include/kvm
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2014-07-08 07:09:01 -0400
committerChristoffer Dall <christoffer.dall@linaro.org>2014-09-18 21:48:52 -0400
commitc1bfb577addd4867a82c4f235824a315d5afb94a (patch)
tree4e2fba53b594691839d2c511862b01c83783e1c2 /include/kvm
parent71afaba4a2e98bb7bdeba5078370ab43d46e67a1 (diff)
arm/arm64: KVM: vgic: switch to dynamic allocation
So far, all the VGIC data structures are statically defined by the *maximum* number of vcpus and interrupts it supports. It means that we always have to oversize it to cater for the worse case. Start by changing the data structures to be dynamically sizeable, and allocate them at runtime. The sizes are still very static though. Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'include/kvm')
-rw-r--r--include/kvm/arm_vgic.h76
1 files changed, 58 insertions, 18 deletions
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index f074539c6ac5..fd1b8f252da1 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -54,19 +54,33 @@
54 * - a bunch of shared interrupts (SPI) 54 * - a bunch of shared interrupts (SPI)
55 */ 55 */
56struct vgic_bitmap { 56struct vgic_bitmap {
57 union { 57 /*
58 u32 reg[VGIC_NR_PRIVATE_IRQS / 32]; 58 * - One UL per VCPU for private interrupts (assumes UL is at
59 DECLARE_BITMAP(reg_ul, VGIC_NR_PRIVATE_IRQS); 59 * least 32 bits)
60 } percpu[VGIC_MAX_CPUS]; 60 * - As many UL as necessary for shared interrupts.
61 union { 61 *
62 u32 reg[VGIC_NR_SHARED_IRQS / 32]; 62 * The private interrupts are accessed via the "private"
63 DECLARE_BITMAP(reg_ul, VGIC_NR_SHARED_IRQS); 63 * field, one UL per vcpu (the state for vcpu n is in
64 } shared; 64 * private[n]). The shared interrupts are accessed via the
65 * "shared" pointer (IRQn state is at bit n-32 in the bitmap).
66 */
67 unsigned long *private;
68 unsigned long *shared;
65}; 69};
66 70
67struct vgic_bytemap { 71struct vgic_bytemap {
68 u32 percpu[VGIC_MAX_CPUS][VGIC_NR_PRIVATE_IRQS / 4]; 72 /*
69 u32 shared[VGIC_NR_SHARED_IRQS / 4]; 73 * - 8 u32 per VCPU for private interrupts
74 * - As many u32 as necessary for shared interrupts.
75 *
76 * The private interrupts are accessed via the "private"
77 * field, (the state for vcpu n is in private[n*8] to
78 * private[n*8 + 7]). The shared interrupts are accessed via
79 * the "shared" pointer (IRQn state is at byte (n-32)%4 of the
80 * shared[(n-32)/4] word).
81 */
82 u32 *private;
83 u32 *shared;
70}; 84};
71 85
72struct kvm_vcpu; 86struct kvm_vcpu;
@@ -127,6 +141,9 @@ struct vgic_dist {
127 bool in_kernel; 141 bool in_kernel;
128 bool ready; 142 bool ready;
129 143
144 int nr_cpus;
145 int nr_irqs;
146
130 /* Virtual control interface mapping */ 147 /* Virtual control interface mapping */
131 void __iomem *vctrl_base; 148 void __iomem *vctrl_base;
132 149
@@ -166,15 +183,36 @@ struct vgic_dist {
166 /* Level/edge triggered */ 183 /* Level/edge triggered */
167 struct vgic_bitmap irq_cfg; 184 struct vgic_bitmap irq_cfg;
168 185
169 /* Source CPU per SGI and target CPU */ 186 /*
170 u8 irq_sgi_sources[VGIC_MAX_CPUS][VGIC_NR_SGIS]; 187 * Source CPU per SGI and target CPU:
188 *
189 * Each byte represent a SGI observable on a VCPU, each bit of
190 * this byte indicating if the corresponding VCPU has
191 * generated this interrupt. This is a GICv2 feature only.
192 *
193 * For VCPUn (n < 8), irq_sgi_sources[n*16] to [n*16 + 15] are
194 * the SGIs observable on VCPUn.
195 */
196 u8 *irq_sgi_sources;
171 197
172 /* Target CPU for each IRQ */ 198 /*
173 u8 irq_spi_cpu[VGIC_NR_SHARED_IRQS]; 199 * Target CPU for each SPI:
174 struct vgic_bitmap irq_spi_target[VGIC_MAX_CPUS]; 200 *
201 * Array of available SPI, each byte indicating the target
202 * VCPU for SPI. IRQn (n >=32) is at irq_spi_cpu[n-32].
203 */
204 u8 *irq_spi_cpu;
205
206 /*
207 * Reverse lookup of irq_spi_cpu for faster compute pending:
208 *
209 * Array of bitmaps, one per VCPU, describing if IRQn is
210 * routed to a particular VCPU.
211 */
212 struct vgic_bitmap *irq_spi_target;
175 213
176 /* Bitmap indicating which CPU has something pending */ 214 /* Bitmap indicating which CPU has something pending */
177 unsigned long irq_pending_on_cpu; 215 unsigned long *irq_pending_on_cpu;
178#endif 216#endif
179}; 217};
180 218
@@ -204,11 +242,11 @@ struct vgic_v3_cpu_if {
204struct vgic_cpu { 242struct vgic_cpu {
205#ifdef CONFIG_KVM_ARM_VGIC 243#ifdef CONFIG_KVM_ARM_VGIC
206 /* per IRQ to LR mapping */ 244 /* per IRQ to LR mapping */
207 u8 vgic_irq_lr_map[VGIC_NR_IRQS]; 245 u8 *vgic_irq_lr_map;
208 246
209 /* Pending interrupts on this VCPU */ 247 /* Pending interrupts on this VCPU */
210 DECLARE_BITMAP( pending_percpu, VGIC_NR_PRIVATE_IRQS); 248 DECLARE_BITMAP( pending_percpu, VGIC_NR_PRIVATE_IRQS);
211 DECLARE_BITMAP( pending_shared, VGIC_NR_SHARED_IRQS); 249 unsigned long *pending_shared;
212 250
213 /* Bitmap of used/free list registers */ 251 /* Bitmap of used/free list registers */
214 DECLARE_BITMAP( lr_used, VGIC_V2_MAX_LRS); 252 DECLARE_BITMAP( lr_used, VGIC_V2_MAX_LRS);
@@ -239,7 +277,9 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write);
239int kvm_vgic_hyp_init(void); 277int kvm_vgic_hyp_init(void);
240int kvm_vgic_init(struct kvm *kvm); 278int kvm_vgic_init(struct kvm *kvm);
241int kvm_vgic_create(struct kvm *kvm); 279int kvm_vgic_create(struct kvm *kvm);
280void kvm_vgic_destroy(struct kvm *kvm);
242int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu); 281int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu);
282void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu);
243void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu); 283void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
244void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu); 284void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
245int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num, 285int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,