diff options
Diffstat (limited to 'include/kvm')
| -rw-r--r-- | include/kvm/arm_vgic.h | 43 | 
1 files changed, 38 insertions, 5 deletions
| diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index ac4888dc86bc..7c55dd5dd2c9 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -33,10 +33,11 @@  #define VGIC_V2_MAX_LRS		(1 << 6)  #define VGIC_V3_MAX_LRS		16  #define VGIC_MAX_IRQS		1024 +#define VGIC_V2_MAX_CPUS	8  /* Sanity checks... */ -#if (KVM_MAX_VCPUS > 8) -#error	Invalid number of CPU interfaces +#if (KVM_MAX_VCPUS > 255) +#error Too many KVM VCPUs, the VGIC only supports up to 255 VCPUs for now  #endif  #if (VGIC_NR_IRQS_LEGACY & 31) @@ -132,6 +133,18 @@ struct vgic_params {  	unsigned int	maint_irq;  	/* Virtual control interface base address */  	void __iomem	*vctrl_base; +	int		max_gic_vcpus; +	/* Only needed for the legacy KVM_CREATE_IRQCHIP */ +	bool		can_emulate_gicv2; +}; + +struct vgic_vm_ops { +	bool	(*handle_mmio)(struct kvm_vcpu *, struct kvm_run *, +			       struct kvm_exit_mmio *); +	bool	(*queue_sgi)(struct kvm_vcpu *, int irq); +	void	(*add_sgi_source)(struct kvm_vcpu *, int irq, int source); +	int	(*init_model)(struct kvm *); +	int	(*map_resources)(struct kvm *, const struct vgic_params *);  };  struct vgic_dist { @@ -140,6 +153,9 @@ struct vgic_dist {  	bool			in_kernel;  	bool			ready; +	/* vGIC model the kernel emulates for the guest (GICv2 or GICv3) */ +	u32			vgic_model; +  	int			nr_cpus;  	int			nr_irqs; @@ -148,7 +164,11 @@ struct vgic_dist {  	/* Distributor and vcpu interface mapping in the guest */  	phys_addr_t		vgic_dist_base; -	phys_addr_t		vgic_cpu_base; +	/* GICv2 and GICv3 use different mapped register blocks */ +	union { +		phys_addr_t		vgic_cpu_base; +		phys_addr_t		vgic_redist_base; +	};  	/* Distributor enabled */  	u32			enabled; @@ -210,8 +230,13 @@ struct vgic_dist {  	 */  	struct vgic_bitmap	*irq_spi_target; +	/* Target MPIDR for each IRQ (needed for GICv3 IROUTERn) only */ +	u32			*irq_spi_mpidr; +  	/* Bitmap indicating which CPU has something pending */  	unsigned long		*irq_pending_on_cpu; + +	struct vgic_vm_ops	vm_ops;  #endif  }; @@ -229,6 +254,7 @@ struct vgic_v3_cpu_if {  #ifdef CONFIG_ARM_GIC_V3  	u32		vgic_hcr;  	u32		vgic_vmcr; +	u32		vgic_sre;	/* Restored only, change ignored */  	u32		vgic_misr;	/* Saved only */  	u32		vgic_eisr;	/* Saved only */  	u32		vgic_elrsr;	/* Saved only */ @@ -275,13 +301,15 @@ struct kvm_exit_mmio;  int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write);  int kvm_vgic_hyp_init(void);  int kvm_vgic_map_resources(struct kvm *kvm); -int kvm_vgic_create(struct kvm *kvm); +int kvm_vgic_get_max_vcpus(void); +int kvm_vgic_create(struct kvm *kvm, u32 type);  void kvm_vgic_destroy(struct kvm *kvm);  void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu);  void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);  void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);  int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,  			bool level); +void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);  int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);  bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run,  		      struct kvm_exit_mmio *mmio); @@ -327,7 +355,7 @@ static inline int kvm_vgic_map_resources(struct kvm *kvm)  	return 0;  } -static inline int kvm_vgic_create(struct kvm *kvm) +static inline int kvm_vgic_create(struct kvm *kvm, u32 type)  {  	return 0;  } @@ -379,6 +407,11 @@ static inline bool vgic_ready(struct kvm *kvm)  {  	return true;  } + +static inline int kvm_vgic_get_max_vcpus(void) +{ +	return KVM_MAX_VCPUS; +}  #endif  #endif |