1 /* 2 * Copyright (C) 2012 ARM Ltd. 3 * Author: Marc Zyngier <marc.zyngier@arm.com> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 */ 18 19 #ifndef __ASM_ARM_KVM_VGIC_H 20 #define __ASM_ARM_KVM_VGIC_H 21 22 #include <linux/kernel.h> 23 #include <linux/kvm.h> 24 #include <linux/irqreturn.h> 25 #include <linux/spinlock.h> 26 #include <linux/types.h> 27 #include <linux/irqchip/arm-gic.h> 28 29 #define VGIC_NR_IRQS 256 30 #define VGIC_NR_SGIS 16 31 #define VGIC_NR_PPIS 16 32 #define VGIC_NR_PRIVATE_IRQS (VGIC_NR_SGIS + VGIC_NR_PPIS) 33 #define VGIC_NR_SHARED_IRQS (VGIC_NR_IRQS - VGIC_NR_PRIVATE_IRQS) 34 #define VGIC_MAX_CPUS KVM_MAX_VCPUS 35 #define VGIC_MAX_LRS (1 << 6) 36 37 /* Sanity checks... */ 38 #if (VGIC_MAX_CPUS > 8) 39 #error Invalid number of CPU interfaces 40 #endif 41 42 #if (VGIC_NR_IRQS & 31) 43 #error "VGIC_NR_IRQS must be a multiple of 32" 44 #endif 45 46 #if (VGIC_NR_IRQS > 1024) 47 #error "VGIC_NR_IRQS must be <= 1024" 48 #endif 49 50 /* 51 * The GIC distributor registers describing interrupts have two parts: 52 * - 32 per-CPU interrupts (SGI + PPI) 53 * - a bunch of shared interrupts (SPI) 54 */ 55 struct vgic_bitmap { 56 union { 57 u32 reg[VGIC_NR_PRIVATE_IRQS / 32]; 58 DECLARE_BITMAP(reg_ul, VGIC_NR_PRIVATE_IRQS); 59 } percpu[VGIC_MAX_CPUS]; 60 union { 61 u32 reg[VGIC_NR_SHARED_IRQS / 32]; 62 DECLARE_BITMAP(reg_ul, VGIC_NR_SHARED_IRQS); 63 } shared; 64 }; 65 66 struct vgic_bytemap { 67 u32 percpu[VGIC_MAX_CPUS][VGIC_NR_PRIVATE_IRQS / 4]; 68 u32 shared[VGIC_NR_SHARED_IRQS / 4]; 69 }; 70 71 struct vgic_dist { 72 #ifdef CONFIG_KVM_ARM_VGIC 73 spinlock_t lock; 74 bool ready; 75 76 /* Virtual control interface mapping */ 77 void __iomem *vctrl_base; 78 79 /* Distributor and vcpu interface mapping in the guest */ 80 phys_addr_t vgic_dist_base; 81 phys_addr_t vgic_cpu_base; 82 83 /* Distributor enabled */ 84 u32 enabled; 85 86 /* Interrupt enabled (one bit per IRQ) */ 87 struct vgic_bitmap irq_enabled; 88 89 /* Interrupt 'pin' level */ 90 struct vgic_bitmap irq_state; 91 92 /* Level-triggered interrupt in progress */ 93 struct vgic_bitmap irq_active; 94 95 /* Interrupt priority. Not used yet. */ 96 struct vgic_bytemap irq_priority; 97 98 /* Level/edge triggered */ 99 struct vgic_bitmap irq_cfg; 100 101 /* Source CPU per SGI and target CPU */ 102 u8 irq_sgi_sources[VGIC_MAX_CPUS][VGIC_NR_SGIS]; 103 104 /* Target CPU for each IRQ */ 105 u8 irq_spi_cpu[VGIC_NR_SHARED_IRQS]; 106 struct vgic_bitmap irq_spi_target[VGIC_MAX_CPUS]; 107 108 /* Bitmap indicating which CPU has something pending */ 109 unsigned long irq_pending_on_cpu; 110 #endif 111 }; 112 113 struct vgic_cpu { 114 #ifdef CONFIG_KVM_ARM_VGIC 115 /* per IRQ to LR mapping */ 116 u8 vgic_irq_lr_map[VGIC_NR_IRQS]; 117 118 /* Pending interrupts on this VCPU */ 119 DECLARE_BITMAP( pending_percpu, VGIC_NR_PRIVATE_IRQS); 120 DECLARE_BITMAP( pending_shared, VGIC_NR_SHARED_IRQS); 121 122 /* Bitmap of used/free list registers */ 123 DECLARE_BITMAP( lr_used, VGIC_MAX_LRS); 124 125 /* Number of list registers on this CPU */ 126 int nr_lr; 127 128 /* CPU vif control registers for world switch */ 129 u32 vgic_hcr; 130 u32 vgic_vmcr; 131 u32 vgic_misr; /* Saved only */ 132 u32 vgic_eisr[2]; /* Saved only */ 133 u32 vgic_elrsr[2]; /* Saved only */ 134 u32 vgic_apr; 135 u32 vgic_lr[VGIC_MAX_LRS]; 136 #endif 137 }; 138 139 #define LR_EMPTY 0xff 140 141 struct kvm; 142 struct kvm_vcpu; 143 struct kvm_run; 144 struct kvm_exit_mmio; 145 146 #ifdef CONFIG_KVM_ARM_VGIC 147 int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write); 148 int kvm_vgic_hyp_init(void); 149 int kvm_vgic_init(struct kvm *kvm); 150 int kvm_vgic_create(struct kvm *kvm); 151 int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu); 152 void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu); 153 void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu); 154 int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num, 155 bool level); 156 int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); 157 bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run, 158 struct kvm_exit_mmio *mmio); 159 160 #define irqchip_in_kernel(k) (!!((k)->arch.vgic.vctrl_base)) 161 #define vgic_initialized(k) ((k)->arch.vgic.ready) 162 163 #else 164 static inline int kvm_vgic_hyp_init(void) 165 { 166 return 0; 167 } 168 169 static inline int kvm_vgic_set_addr(struct kvm *kvm, unsigned long type, u64 addr) 170 { 171 return 0; 172 } 173 174 static inline int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write) 175 { 176 return -ENXIO; 177 } 178 179 static inline int kvm_vgic_init(struct kvm *kvm) 180 { 181 return 0; 182 } 183 184 static inline int kvm_vgic_create(struct kvm *kvm) 185 { 186 return 0; 187 } 188 189 static inline int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) 190 { 191 return 0; 192 } 193 194 static inline void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu) {} 195 static inline void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu) {} 196 197 static inline int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, 198 unsigned int irq_num, bool level) 199 { 200 return 0; 201 } 202 203 static inline int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu) 204 { 205 return 0; 206 } 207 208 static inline bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run, 209 struct kvm_exit_mmio *mmio) 210 { 211 return false; 212 } 213 214 static inline int irqchip_in_kernel(struct kvm *kvm) 215 { 216 return 0; 217 } 218 219 static inline bool vgic_initialized(struct kvm *kvm) 220 { 221 return true; 222 } 223 #endif 224 225 #endif 226